webentwicklung-frage-antwort-db.com.de

Ist es möglich, die Breite des übergeordneten Elements beizubehalten, wenn position: fixed angewendet wird?

Wenn wir position:fixed auf ein Element anwenden, wird es aus dem normalen Fluss genommen des Dokuments, daher wird die Elementbreite des übergeordneten Elements nicht berücksichtigt. Gibt es Möglichkeiten, die Breite des übergeordneten Elements zu erben wenn dies als Prozentsatz deklariert ist ? (funktionierender Anwendungsfall unten)

let widthis = $('.box').width();
$('.dimensions').text(`width is ${widthis}`);

$('button').on('click', function() {
  $('.box').toggleClass('fixed');
  let widthis = $('.box').width();
  $('.dimensions').text(`width is ${widthis}`);
});
.container {
  max-width: 500px;
  height: 1000px;
}

.box {
  background-color: lightgreen;
}

.fixed {
  position: fixed;
}

.col-1 {
  border: 1px solid red;
  float: left;
  width: 29%;
}

.col-2 {
  border: 1px solid pink;
  float: left;
  width: 69%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click this to toggle position fixed for the left column</button>
<div class="container">
  <div class="col-1">
    <div class="box">
      fixed content<br>
      <span class="dimensions"></span>
    </div>
    </div>
  
  <div class="col-2">
    some other content
    </div>
  </div>
42
George Katsanos

Dies ist eine interessante Herausforderung. Um dies zu erreichen, müssen wir zunächst verstehen, was fixed tatsächlich tut.

Behoben verstehen

Im Gegensatz zu absolute positioniert sich fixed nicht von seinem nächsten relativen übergeordneten Element. Stattdessen positioniert sich fixed relativ zum Ansichtsfenster . Das Ansichtsfenster bleibt immer fixiert, weshalb Sie den Effekt erhalten, den Sie erzielen.

Davon abgesehen , wenn Sie eine beliebige Breite "erben", entspricht dies dem Ansichtsfenster . Es nützt uns also nichts, wenn wir versuchen, die Breite unseres Zielelements auf die Breite seines übergeordneten Elements einzustellen.

Erfahren Sie mehr über die verschiedenen Verhaltensweisen von Position .

Schnelle Lösungen

Es gibt zwei Ansätze, um dies zu beheben.

Reines CSS

Wir können reines CSS verwenden, um dieses Problem zu beheben, aber wir müssten die Breite im Voraus kennen . Angenommen, das übergeordnete Element ist 300px;

.parent{
    width: 300px;
}

.parent .fixed_child{
    position: fixed;
    width: 300px;
}

JS

Jetzt mit mobilen Geräten , wir nicht wirklich haben den Luxus, Breiten zu setzen, insbesondere alles über 300px. Die Verwendung von Prozentsätzen funktioniert auch nicht, da sie sich auf das Ansichtsfenster und nicht auf das übergeordnete Element bezieht. Wir können JS verwenden, in diesem Fall mit jQuery, um dies zu erreichen . Werfen wir einen Blick auf eine Funktion , mit der immer die Breite des Parens festlegt t im gegebenen Moment:

 function toggleFixed () {
      var parentwidth = $(".parent").width();      
      $(".child").toggleClass("fixed").width(parentwidth);        
  }

cSS:

.fixed{
    position:fixed;
}

Anzeigen in CodePen

Dynamische Breiten

Das ist in Ordnung, aber was passiert , wenn sich die Breite des Fensters ändert , während sich der Benutzer noch auf der Seite befindet, und das übergeordnete Element damit ändert? Während der Elternteil seine Breite anpassen kann, bleibt das Kind die eingestellte Breite, die die Funktion es festgelegt hat. Wir können dies mit jQuery'sresize() Ereignis-Listener beheben. Zuerst müssen wir die von uns erstellte Funktion in zwei Teile aufteilen:

function toggleFixed() {
   adjustWidth();
   $(".child").toggleClass("fixed");
 }

 function adjustWidth() {
   var parentwidth = $(".parent").width();
   $(".child").width(parentwidth);
 }

Nachdem wir jeden Teil getrennt haben, können wir sie einzeln aufrufen. Wir fügen unsere ursprüngliche Schaltflächenmethode hinzu, mit der die feste und die Breite umgeschaltet werden:

$("#fixer").click(
     function() {
       toggleFixed();
     });

Und jetzt fügen wir auch den Resize Event Listener zum Fenster hinzu:

 $(window).resize(
     function() {
       adjustWidth();
     })

Anzeigen in CodePen

Dort! Jetzt haben wir ein festes Element, dessen Größe angepasst wird, wenn die Größe des Fensters geändert wird.

Fazit

Wir haben uns dieser Herausforderung gestellt, indem wir die Position fixed und ihre Grenzen verstanden haben. Im Gegensatz zu "Absolut" bezieht sich "fixed" nur auf den Ansichtsport und kann daher nicht die Breite des übergeordneten Elements erben.

Um dies zu lösen, müssen wir etwas JS-Magie verwenden, was mit jQuery nicht sehr viel gekostet hat, um dies zu erreichen.

In einigen Fällen benötigen wir einen dynamischen Ansatz mit Skalierungsgeräten unterschiedlicher Breite. Wieder haben wir den JS-Ansatz gewählt.

32
Philll_t

Sie können width:inherit verwenden. Dadurch wird das Elternteil angehört. Ich teste es und es funktioniert in Firefox.

11
egon12

Die Breite ändert sich, da das Objekt, wenn statisch seine prozentuale Breite von seinem übergeordneten Objekt erhält. Wenn Sie das Objekt auf "Fest" gesetzt haben, ist es nicht mehr im Fluss und ändert seine Größe. 

Sie müssen Ihrem Nav-Menü eine eigene Größe zuweisen und dürfen nicht erwarten, dass das Element seine Breite vom übergeordneten Element erhält.

.nav {
    position: fixed;
    width: 20%;
    border: 1px solid green;
    padding: 0px;
    list-style-type:none;
    background:lightblue;
}

http://tinker.io/3458e/5

5
Michael Rader

Hallo, du könntest auch Jquery verwenden, um die Breite zu behalten. Zum Beispiel:

jQuery(function($) {
    function fixDiv() {
        var $cache = $('#your-element');
        var $width = $('#your-element').parent().width();
        if ($(window).scrollTop() > 100) {
            $cache.css({
                'position': 'fixed',
                'top': '10px',
                'width': $width
            });
        } else {
            $cache.css({
                'position': 'relative',
                'top': 'auto'
            });
        }
    }
    $(window).scroll(fixDiv);
    fixDiv();
 });
4
khoekman

Dies ist wahrscheinlich auf einen gewissen Rand oder Abstand des Elements <html> oder <body> zurückzuführen. Wenn es statisch ist, wird die Größe basierend auf der Breite von <body> festgelegt. Wenn sie jedoch in position:fixed geändert wird, wird die Größe in Bezug auf das Ansichtsfenster geändert.

Wenn Sie also diesen Standardrand/-abstand entfernen, sollte dies das Problem beheben (meiner Erfahrung nach body { margin:0; } behebt das Problem). Wenn Sie die Größe ändern, wenn sie behoben ist (wie width:calc(n% - 5px);).

3
Zach Saucier

Wie schon jemand vermuten lässt, ist die Verwendung von Javascript die beste Lösung.

Ohne jQuery.

const parentElement = document.querySelector('.parent-element');
const fixedElement = document.querySelector('.fixed-element');

// get parent-element width when page is fully loaded
// and change fixed-element width accordingly
window.addEventListener('load', changeFixedElementWidth);

// get parent-element width when window is resized
// and change fixed-element width accordingly
window.addEventListener('resize', changeFixedElementWidth);

function changeFixedElementWidth() {
  const parentElementWidth = parentElement.getBoundingClientRect().width;
  fixedElement.style.width = parentElementWidth + 'px';
}
2
pldg

Eine Problemumgehung könnte sein: left:8px; right:0; width:18%; im CSS für das nav . Nicht die beste Lösung.

0
Simke Nys