Est-il possible de conserver la largeur de l'élément parent lorsque la position: fixe est appliquée?

Lorsque nous appliquons position:fixed pour un élément, il est pris hors de la circulation normale du document, donc il ne respecte pas la largeur de l'élément parent. Est-il possible de faire hériter du parent largeur si ceci est déclaré en pourcentage<!--8 ? (travail de cas d'utilisation ci-dessous)

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>
37
demandé sur George Katsanos 2013-04-15 19:02:28

8 réponses

C'est un défi intéressant. Pour cette approche, nous devons d'abord comprendre ce qu' fixed en fait si.

Comprendre Fixe

pas comme absolute,fixed ne se positionne pas par rapport à son parent le plus proche parent. Au lieu de cela, fixedse positionne par rapport à la fenêtre d'affichage. La fenêtre restera toujours fixe, c'est pourquoi vous obtenez l'effet que vous faites.

cela étant dit, chaque fois que vous "heter" n'importe quelle largeur il sera respectif au viewport. Donc, il n'est pas bon lorsque nous tentons de définir la largeur de notre élément cible à la largeur de son parent.

en Savoir plus sur les différents comportements de position.

Solutions Rapides

il y a deux approches pour corriger cela.

pur CSS

nous pouvons utiliser pur CSS pour résoudre ce problème, mais nous besoin de connaître la largeur d'avance. Supposons que son élément parent 300px;

.parent{
    width: 300px;
}

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

JS

appareils mobiles nous ne pas vraiment le luxe d'avoir largeur des ensembles, surtout n'importe quoi sur 300px. L'utilisation de pourcentages ne fonctionnera pas non plus, puisqu'elle sera relative à l'élément viewport et non à l'élément parent. nous pouvons utiliser JS, dans ce cas avec jQuery pour réaliser ce. Permet de jeter un coup d'oeil à functiondéfinira toujours la largeur du paren t au moment donné:

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

css:

.fixed{
    position:fixed;
}

Vue CodePen

Largeurs Dynamiques

C'est bien beau, mais ce qui se passe si la largeur de la fenêtre change pendant que l'utilisateur est encore sur la page, Changer le parent élément avec cela? Tandis que le parent peut ajuster sa largeur, l'enfant restera la largeur définie par la fonction. On peut corriger ça avec jQueryresize() écouteur d'événement. Tout d'abord, nous devons diviser la fonction que nous avons créée en deux:

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

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

maintenant que nous avons séparé chaque partie, nous pouvons les appeler individuellement, nous allons inclure notre méthode originale de bouton qui bascule le fixe et la largeur:

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

et maintenant nous ajoutons aussi redimensionner écouteur d'événement à la fenêtre:

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

Vue CodePen

Il y! Nous avons maintenant un élément fixe dont la taille sera ajustée lorsque la fenêtre sera redimensionnée.

Conclusion

nous avons relevé ce défi en comprenant fixed position et ses limites. À La Différence Absolue, fixed ne concerne que le port de vue et ne peut donc hériter de la largeur de son parent.

à résoudre ceci, nous avons besoin d'utiliser de la magie JS, qui n'a pas pris grand chose avec jQuery, pour y arriver.

dans certains cas, nous avons besoin d'une approche dynamique avec des dispositifs de mise à l'échelle de largeurs variables. Encore une fois, nous avons adopté l'approche JS.

22
répondu Philll_t 2017-03-19 23:58:19

Vous pouvez utiliser width:inherit. Ça le fera écouter à parent. Je le teste et ça marche dans Firefox.

14
répondu egon12 2015-05-03 01:44:28

la largeur change parce que l'objet reçoit sa largeur en pourcentage de sa base. Une fois que vous avez réglé l'objet sur fixe, il n'est plus dans flow et redimensionne.

vous allez devoir définir une taille à votre menu nav tout seul et ne pas vous attendre à ce que l'élément obtienne sa largeur à partir du parent.

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

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

5
répondu Michael Rader 2014-11-06 21:28:59

Salut Vous pouvez aussi utiliser jquery pour garder la largeur. Par exemple:

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
répondu khoekman 2015-07-09 10:12:23

ceci est probablement dû à une certaine marge par défaut ou un rembourrage sur le <html> ou <body> élément. Quand il est statique, il tailles basées sur le <body>'largeur à l'époque, mais quand il se transforme en position:fixed c'est la taille par rapport au viewport.

en tant que tel, la suppression de cette marge par défaut/rembourrage devrait corriger le problème (dans mon expérience body { margin:0; } fixe) devrait changer la taille quand il est fixe (comme width:calc(n% - 5px);).

3
répondu Zach Saucier 2015-05-03 01:58:03

comme quelqu'un l'a déjà suggéré, utiliser javascript est la meilleure solution.

sans 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
répondu pldg 2018-07-14 17:52:42

Une solution de contournement pourrait être: left:8px; right:0; width:18%; dans le CSS pour le nav. Pas la meilleure solution.

0
répondu Simke Nys 2015-05-03 01:44:48

Ajouter width:auto; à l'élément position:fixed; pour faire sa largeur égale à la largeur de son élément parent.

-2
répondu Naveen Attri 2016-01-15 10:59:51