Position fixe mais relative au conteneur

639

J'essaie de corriger un divafin qu'il colle toujours en haut de l'écran, en utilisant:

position: fixed;
top: 0px;
right: 0px;

Cependant, le divest à l'intérieur d'un conteneur centré. Lorsque je l'utilise, position:fixedil corrige le divrelatif à la fenêtre du navigateur, comme il est contre le côté droit du navigateur. Au lieu de cela, il doit être fixe par rapport au conteneur.

Je sais que cela position:absolutepeut être utilisé pour corriger un élément par rapport à la div, mais lorsque vous faites défiler la page, l'élément disparaît et ne colle pas au sommet comme avec position:fixed.

Existe-t-il un hack ou une solution de contournement pour y parvenir?

Zach Nicodemous
la source
"Tether est une bibliothèque d'interface utilisateur de bas niveau qui peut être utilisée pour positionner n'importe quel élément sur une page à côté de tout autre élément." github.com/shipshapecode/tether + Demos / Docs sur tether.io
Kai Noack

Réponses:

408

Réponse courte: non. (C'est maintenant possible avec la transformation CSS. Voir l'édition ci-dessous)

Réponse longue: Le problème avec l'utilisation du positionnement "fixe" est qu'il retire l'élément du flux . il ne peut donc pas être repositionné par rapport à son parent car c'est comme s'il n'en avait pas. Si, cependant, le conteneur est d'une largeur connue et fixe, vous pouvez utiliser quelque chose comme:

#fixedContainer {
  position: fixed;
  width: 600px;
  height: 200px;
  left: 50%;
  top: 0%;
  margin-left: -300px; /*half the width*/
}

http://jsfiddle.net/HFjU6/1/

Modifier (03/2015):

Ce sont des informations obsolètes. Il est désormais possible de centrer le contenu d'une taille dynamique (horizontalement et verticalement) à l'aide de la magie de la transformation CSS3. Le même principe s'applique, mais au lieu d'utiliser la marge pour compenser votre conteneur, vous pouvez utiliser translateX(-50%). Cela ne fonctionne pas avec l'astuce de marge ci-dessus, car vous ne savez pas combien le compenser, sauf si la largeur est fixe et vous ne pouvez pas utiliser de valeurs relatives (comme 50%), car elles seront relatives au parent et non à l'élément qu'il est. appliqué à. transformse comporte différemment. Ses valeurs sont relatives à l'élément auquel elles sont appliquées. Ainsi, 50%pour transformsignifie la moitié de la largeur de l'élément, tandis que 50%pour margin correspond à la moitié de la largeur du parent. Ceci est une solution IE9 +

En utilisant un code similaire à l'exemple ci-dessus, j'ai recréé le même scénario en utilisant une largeur et une hauteur complètement dynamiques:

.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    left: 50%;
    top: 0%;
    transform: translateX(-50%);
}

Si vous voulez qu'il soit centré, vous pouvez aussi le faire:

.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

Démos:

jsFiddle: Centré horizontalement que
jsFiddle: Centré à la fois horizontalement et verticalement
crédit d' origine va à l' utilisateur aaronk6 pour elle en me montrant dans cette réponse

Joseph Marikle
la source
A fonctionné magnifiquement pour moi. Bien que j'avais besoin du mien à gauche et déjà centré, div non fixé, donc je devais juste diminuer la marge gauche jusqu'à ce qu'elle soit alignée. Aucun reste aligné quelle que soit la largeur des fenêtres. Merci. +1
Iain M Norman
9
@Joseph aucune idée pourquoi position:fixedsans préciser topou fonctionne left parfois ? Certains navigateurs semblent par défaut l'élément à l'endroit où il serait normalement, s'il avait un positionnement normal. stackoverflow.com/questions/8712047/…
Flash
2
qu'en est-il sans hauteur et largeur fixes? Dans mon cas, je n'ai donné aucune largeur de signal à aucun conteneur, même jusqu'à la balise body. Quelle solution vous me direz de faire.
mfq
1
@mfq Malheureusement, cette méthode ne fonctionnera pas du tout sans une hauteur et une largeur connues. Ce que vous allez faire dépendra en grande partie de ce que vous essayez de centrer. S'il s'agit d'une image, utilisez-la simplement comme arrière-plan d'un conteneur 100% x 100%. S'il s'agit d'un élément réel qui est complètement dynamique, vous devrez probablement explorer en utilisant une solution javascript pour obtenir les dimensions.
Joseph Marikle
2
J'ai trouvé que l'ajout left:inherità l'élément de position fixe peut forcer le navigateur à respecter le décalage du parent.
Willster
181

En fait, cela est possible et la réponse acceptée ne concerne que la centralisation, ce qui est assez simple. De plus, vous n'avez vraiment pas besoin d'utiliser JavaScript.

Cela vous permettra de gérer n'importe quel scénario:

Configurez tout comme vous le feriez si vous voulez positionner: absolu à l'intérieur d'une position: conteneur relatif, puis créez une nouvelle div à position fixe à l'intérieur de la div avec position: absolute, mais ne définissez pas ses propriétés supérieure et gauche. Il sera ensuite fixé où vous le souhaitez, par rapport au conteneur.

Par exemple:

/* Main site body */
.wrapper {
    width: 940px;
    margin: 0 auto;
    position: relative; /* Ensure absolute positioned child elements are relative to this*/
}

/* Absolute positioned wrapper for the element you want to fix position */
.fixed-wrapper {
    width: 220px;
    position: absolute;
    top: 0;
    left: -240px; /* Move this out to the left of the site body, leaving a 20px gutter */
}

/* The element you want to fix the position of */
.fixed {
    width: 220px;
    position: fixed;
    /* Do not set top / left! */
}
<div class="wrapper">
    <div class="fixed-wrapper">
        <div class="fixed">
            Content in here will be fixed position, but 240px to the left of the site body.
        </div>
    </div>
</div>

Malheureusement, j'espérais que ce fil pourrait résoudre mon problème avec le WebKit d'Android rendant les pixels de flou de l'ombre en tant que marges sur les éléments de position fixe, mais il semble que ce soit un bug.
Quoi qu'il en soit, j'espère que cela aide!

Graeme Blackwood
la source
1
Pas tout à fait, mais c'est un bon début. S'il y a beaucoup d'espace en dessous de .wrapper, votre .fixed-wrapper se terminera au bas du parent mais votre élément .fixed continuera à couler hors des deux conteneurs et dans tout contenu ci-dessous. Comme je l'ai dit, c'est un bon début, pas parfait, mais je ne vois pas comment cela peut être accompli sans quelques js.
o_O
4
Cependant, cela ne fonctionne pas bien avec une conception fluide.
Zuhaib Ali,
3
j'ai essayé de le faire, mais au fur et à mesure que je défile vers le bas, l'en-tête que j'avais appliqué fixe (avec l'absolu parent auquel le parent était relatif) ne bougeait pas lorsque je fais défiler.
Mirage
Cela a fonctionné pour moi avec un div en haut à droite dans Chromium et Firefox, sauf que les positions verticales du div fixe étaient différentes (sur Chromium, il était au-dessus du div parent, sur Firefox, il était à l'intérieur).
Damien
2
C'était la réponse pour moi! Merci @Graeme Blackwood
Tabu.Net
136

Oui, selon les spécifications, il existe un moyen.

Bien que je convienne que Graeme Blackwood devrait être la réponse acceptée, car elle résout pratiquement le problème, il convient de noter qu'un élément fixe peut être positionné par rapport à son conteneur.

J'ai remarqué par accident qu'en postulant

-webkit-transform: translateZ(0);

au corps, il a fait un enfant fixe par rapport à lui (au lieu de la fenêtre). Donc, mes éléments leftet toppropriétés fixes étaient désormais relatifs au conteneur.

J'ai donc fait quelques recherches, et j'ai constaté que le problème était déjà couvert par Eric Meyer et même si cela ressemblait à un "truc", il s'avère que cela fait partie des spécifications:

Pour les éléments dont la disposition est régie par le modèle de boîte CSS, toute valeur autre que aucune pour la transformation entraîne la création à la fois d'un contexte d'empilement et d'un bloc conteneur. L'objet agit comme un bloc conteneur pour les descendants positionnés fixes.

http://www.w3.org/TR/css3-transforms/

Ainsi, si vous appliquez une transformation à un élément parent, il deviendra le bloc conteneur.

Mais...

Le problème est que l'implémentation semble boguée / créative, car les éléments cessent également de se comporter comme fixes (même si ce bit ne semble pas faire partie de la spécification).

Le même comportement se retrouvera dans Safari, Chrome et Firefox, mais pas dans IE11 (où l'élément fixe restera toujours fixe).

Une autre chose intéressante (non documentée) est que lorsqu'un élément fixe est contenu à l'intérieur d'un élément transformé, alors que ses propriétés topet leftseront désormais liées au conteneur, en respectant la box-sizingpropriété, son contexte de défilement s'étendra sur la bordure de l'élément, comme si une boîte -sizing a été défini sur border-box. Pour certains créatifs, cela pourrait devenir un jouet :)

TESTER

Francesco Frapporti
la source
4
Cela m'a permis de créer une table avec des en-têtes fixes à l'intérieur d'un conteneur
Zach Saucier
Bien, cela fonctionne pour moi dans Chrome. Des idées sur la façon de réaliser la même chose dans IE? J'ai essayé d'utiliser translateZ, mais il ne l'a pas fait dans n'importe quelle version d'IE.
Anish Patel
Idem .. quelqu'un sait-il comment faire cela dans IE? son genre de douleur à détecter le navigateur, puis à montrer systématiquement ou à ne pas montrer left:(étant donné que ça gâche)
Tallboy
Je remplis simplement la condition opposée dont j'ai besoin fixée dans un conteneur relatif mais modifiée par la propriété transform. Votre réponse est très utile, merci!
mytharcher
8
@Francesco Frapporti semble que cela ne fonctionne plus ... de toute façon dans la dernière version de Chrome (Version 42.0.2311.90) :(
jjenzz
60

La réponse est oui, tant que vous ne définissez pas left: 0ou right: 0après avoir défini la position div sur fixe.

http://jsfiddle.net/T2PL5/85/

Vérifiez la div de la barre latérale. Il est fixe, mais lié au parent, pas au point de vue de la fenêtre.

body { background: #ccc; }

.wrapper {
    margin: 0 auto;
    height: 1400px;
    width: 650px;
    background: green;
}

.sidebar {
    background-color: #ddd;
    float: left;
    width: 300px;
    height: 100px;
    position: fixed;
}

.main {
    float: right;
    background-color: yellow;
    width: 300px;
    height: 1400px;
}

<div class="wrapper">wrapper
    <div class="sidebar">sidebar</div>
    <div class="main">main</div>
</div>
Shadow_boi
la source
12
Une raison pour laquelle cela n'obtient pas plus de votes positifs? Semble la solution la plus évidente pour moi.
Trace
Qu'en est-il de la compatibilité entre navigateurs? Avez-vous vérifié cela?
Alexandre Bourlier
3
Ceci est correct mais uniquement pour le «positionnement» de l'élément fixe. Il ne respectera pas la largeur du conteneur ni ne sera redimensionné en aucune façon. Par exemple, si vous avez une enveloppe fluide avec max-width: 1000px; marge: auto; cela ne fonctionnera pas. Si tout peut avoir une largeur fixe, alors oui, cela résoudra votre problème.
Rhys
3
@AlexandreBourlier Oui, cela a bien fonctionné pour moi pour un élément fixe dans Chrome, Firefox et IE11 au moins.
Jason Frank
Fonctionne parfaitement. A dû ajouter une marge gauche: X% pour amener l'élément à droite du conteneur
Anand
45

position: stickyc'est une nouvelle façon de positionner des éléments qui est conceptuellement similaire à position: fixed. La différence est qu'un élément avec position: stickyse comporte comme position: relativedans son parent, jusqu'à ce qu'un seuil de décalage donné soit atteint dans la fenêtre.

Dans Chrome 56 (actuellement bêta en décembre 2016, stable en janvier 2017), la position: le sticky est de retour.

https://developers.google.com/web/updates/2016/12/position-sticky

Plus de détails sont dans Stick your atterrissages! position: terres collantes dans WebKit .

PoseLab
la source
Cela rend la vie tellement plus facile, le seul problème est que l'adhésif n'est pas pris en charge dans Internet Explorer ou Edge 15 et les versions antérieures.
ricks
1
position:stickyc'est super. Pris en charge par tous les navigateurs sauf IE caniuse.com/#feat=css-sticky
Yarin
lol, so old api, and you save my day ... im 'using it for fixed columns for flex tables.
Vladislav Gritsenko
1
"au sein de son parent" - est-il possible de conserver l'élément collant en haut, soit si le parent fait défiler vers le haut est devenu invisible?
Fikret
28

SOLUTION 2019: vous pouvez utiliser la position: stickypropriété.

Voici un exemple CODEPEN démontrant l'utilisation et en quoi elle diffère position: fixed.

Son comportement est expliqué ci-dessous:

  1. Un élément avec une position collante est positionné en fonction de la position de défilement de l'utilisateur. Il agit essentiellement comme position: relativejusqu'à ce qu'un élément défile au-delà d'un décalage spécifique, auquel cas il se transforme en position: fixe. Quand il est défilé, il revient à sa position précédente (relative).

  2. Il affecte le flux d'autres éléments de la page, c'est-à-dire qu'il occupe un espace spécifique sur la page (tout comme position: relative).

  3. S'il est défini à l'intérieur d'un conteneur, il est positionné par rapport à ce conteneur. Si le conteneur a un débordement (scroll), en fonction du décalage de scroll, il se transforme en position: fixe.

Donc, si vous souhaitez obtenir la fonctionnalité fixe mais à l'intérieur d'un conteneur, utilisez le sticky.

Pransh Tiwari
la source
Belle solution. Je ne savais pas position: stickyencore. Beaucoup aidé, merci!
dave0688
J'étais sur le point de poster ceci. Bonne réponse! collant est le chemin.
dkellner
Si vous augmentez la taille de la fenêtre de sortie dans Codepen, l'élément fixe n'est pas fixe mais monte. Pas bon. Une meilleure solution le maintient ancré au bas de la fenêtre.
AndroidDev Il y a
@AndroidDev Seul l'élément supérieur est défini pour être fixé pour la page entière. Il est rendu comme souhaité. Les autres éléments sont des exemples explicatifs pour différents cas.
Pransh Tiwari Il y a
18

Il suffit de retirer les styles haut et gauche de la position fixe div. Voici un exemple

<div id='body' style='height:200%; position: absolute; width: 100%; '>
    <div id='parent' style='display: block; margin: 0px auto; width: 200px;'>
        <div id='content' style='position: fixed;'>content</div>
    </div>
</div> 

Le div #content sera assis là où se trouve le div parent, mais y sera fixé.

Hobberwickey
la source
3
Pourquoi le moins? Cela fonctionne parfaitement pour fixer un élément où vous le souhaitez dans le flux du DOM. deadlykitten.com/tests/fixedPositionTest.php
hobberwickey
18

J'ai créé ce plugin jQuery pour résoudre un problème similaire que je rencontrais lorsque j'avais un conteneur centré (données tabulaires), et je voulais que l'en-tête soit fixé en haut de la page lorsque la liste était défilée, mais je voulais qu'il soit ancré à les données tabulaires pour qu'elles se trouvent partout où je place le conteneur (centré, gauche, droite) et lui permettent également de se déplacer vers la gauche et la droite avec la page lors d'un défilement horizontal.

Voici le lien vers ce plugin jQuery qui peut résoudre ce problème:

https://github.com/bigspotteddog/ScrollToFixed

La description de ce plugin est la suivante:

Ce plugin est utilisé pour fixer des éléments en haut de la page, si l'élément aurait défilé hors de vue, verticalement; cependant, cela permet à l'élément de continuer à se déplacer vers la gauche ou la droite avec le défilement horizontal.

Étant donné une option marginTop, l'élément cessera de se déplacer verticalement vers le haut une fois que le défilement vertical aura atteint la position cible; mais l'élément se déplacera toujours horizontalement lorsque la page défile vers la gauche ou la droite. Une fois que la page a été défilée vers le bas en passant la position cible, l'élément sera restauré à sa position d'origine sur la page.

Ce plugin a été testé dans Firefox 3/4, Google Chrome 10/11, Safari 5 et Internet Explorer 8/9.

Utilisation pour votre cas particulier:

<script src="scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery-scrolltofixed-min.js" type="text/javascript"></script>

$(document).ready(function() {
    $('#mydiv').scrollToFixed();
});
bigspotteddog
la source
12

J'ai dû le faire avec une publicité que mon client voulait placer en dehors de la zone de contenu. J'ai simplement fait ce qui suit et cela a fonctionné comme un charme!

<div id="content" style="position:relative; width:750px; margin:0 auto;">
  <div id="leftOutsideAd" style="position:absolute; top:0; left:-150px;">
    <a href="#" style="position:fixed;"><img src="###" /></a>
  </div>
</div>
Eric K
la source
Mon annonce mesurait 140 pixels de large, je l'ai donc déplacée de 150 pixels vers la gauche pour lui donner un peu de marge droite contre le bord du cadre du site Web.
Eric K
7

Deux éléments HTML et CSS pur (navigateurs modernes)

Voir cet exemple jsFiddle.Redimensionnez et voyez comment les éléments fixes se déplacent même avec les éléments flottants dans lesquels ils se trouvent. Utilisez la barre de défilement la plus à l'intérieur pour voir comment le défilement fonctionnerait sur un site (les éléments fixes restant fixes).

Comme beaucoup ici ont dit, une clé ne fixe pas de tous les paramètres de position sur l' fixedélément (pas top, right, bottomou leftvaleurs).

Au lieu de cela, nous plaçons tous les éléments fixes (notez comment la dernière boîte en a quatre) en premier dans la boîte dont ils doivent être positionnés, comme ceci:

<div class="reference">
  <div class="fixed">Test</div>
  Some other content in.
</div>

Ensuite, nous les utilisons margin-topet margin-leftles "déplaçons" par rapport à leur conteneur, quelque chose comme ce CSS:

.fixed {
    position: fixed;
    margin-top: 200px; /* Push/pull it up/down */
    margin-left: 200px; /* Push/pull it right/left */
}

Notez que parce que les fixedéléments ignorent tous les autres éléments de mise en page, le conteneur final de notre violon peut avoir plusieurs fixedéléments et avoir toujours tous ces éléments liés au coin supérieur gauche. Mais cela n'est vrai que s'ils sont tous placés en premier dans le conteneur, car ce violon de comparaison montre que s'il est dispersé dans le contenu du conteneur, le positionnement devient peu fiable .

Que le wrapper soit statique , relatif ou absolu dans le positionnement, cela n'a pas d'importance.

ScottS
la source
3

Vous pouvez essayer mon plugin jQuery, FixTo .

Usage:

$('#mydiv').fixTo('#centeredContainer');
Burak
la source
2

Une autre solution étrange pour atteindre une position fixe relative consiste à convertir votre conteneur en un iframe, de cette façon, votre élément fixe peut être fixé à la fenêtre du conteneur et non à la page entière.

Beto Aveiga
la source
2

Avec du CSS pur, vous ne pouvez pas y arriver; du moins je ne l'ai pas fait. Cependant, vous pouvez le faire avec jQuery très simplement. Je vais expliquer mon problème, et avec un peu de changement, vous pouvez l'utiliser.

Donc, pour commencer, je voulais que mon élément ait un sommet fixe (du haut de la fenêtre) et un composant gauche à hériter de l'élément parent (car l'élément parent est centré). Pour définir le composant gauche, placez simplement votre élément dans le parent et définissezposition:relative pour l'élément parent.

Ensuite, vous devez savoir combien votre élément est en haut lorsque la barre de défilement est en haut (y zéro défilé); il y a encore deux options. Tout d'abord, c'est statique (un certain nombre) ou vous devez le lire à partir de l'élément parent.

Dans mon cas, c'est à 150 pixels du sommet statique. Donc, quand vous voyez 150, c'est combien l'élément est en haut quand nous n'avons pas fait défiler.

CSS

#parent-element{position:relative;}
#promo{position:absolute;}

jQuery

$(document).ready(function() { //This check window scroll bar location on start
    wtop=parseInt($(window).scrollTop());
    $("#promo").css('top',150+wtop+'px');

});
$(window).scroll(function () { //This is when the window is scrolling
    wtop=parseInt($(window).scrollTop());
    $("#promo").css('top',150+wtop+'px');
});
Mr Br
la source
Le problème est que le div en question scintille lors du défilement.
vvohra87
Probablement parce que le défilement est trop rafraîchissant ou trop rapide. Je n'ai pas eu ce problème tbh, mais je peux vous suggérer d'essayer d'utiliser un "bloqueur" global qui serait actualisé par exemple toutes les 10 ms ou quelque temps, et réglé sur une valeur de blocage à chaque fois que vous faites un changement de hauteur. Bien sûr, vous devez ajouter une condition if à l'événement .scroll qui vérifie si, dans cette période (10 ms), vous avez déjà fait défiler div. Je répète, je n'ai pas essayé, mais je pense que cela pourrait fonctionner :) De cette façon, vous pourriez empêcher div de changer trop sa position afin que l'ordinateur ne puisse pas réellement suivre, et assez pour que l'œil humain le voie.
Mr Br
J'ai déjà donné votre réponse +1 compagnon;) La difficulté à attacher une méthode de boucle globale est vraiment la performance. Faire fonctionner quelque chose comme ça sur des PC et des tablettes plus anciens est pénible. Souvent, un développeur junior au travail a écrit un «var x» dans une telle méthode, ce qui entraîne des fuites de mémoire inutiles si la page reste ouverte trop longtemps: P Mais oui, votre suggestion semble être la seule vraie option.
vvohra87
Vous avez réussi avec des boucles globales; n'est pas bon, je suis d'accord. J'aime juste penser à ce genre de problèmes, c'est pourquoi j'ai écrit une autre suggestion :) Tbh, maintenant je la regarde un peu mieux, je l'éviterais xD J'ai maintenant une autre solution. Ce que vous dites sur la définition de setTimeout () sur un événement de défilement qui appelle func. qui fait le mouvement div .. vous utilisez également le bloqueur global qui est défini sur true en attendant le délai d'expiration et lorsque le délai est appelé, vous retournez le bloqueur sur faux qui permet un autre appel après un certain temps ... de cette façon, vous n'utiliseriez pas la boucle globale mais ont toujours le contrôle sur la fréquence du mouvement div.
Mr Br
C'est plus élégant mais j'ai du mal à l'accepter. C'est le genre de chose que j'attends des spécifications html et css pour gérer tbh. Je déteste le fait que js soit impliqué en premier lieu!
vvohra87
1

C'est facile (selon HTML ci-dessous)

L'astuce consiste à ne PAS utiliser le haut ou la gauche sur l'élément (div) avec "position: fixed;". Si ceux-ci ne sont pas spécifiés, l'élément "contenu fixe" apparaîtra RELATIF à l'élément englobant (le div avec "position: relative;") AU LIEU DE par rapport à la fenêtre du navigateur !!!

<div id="divTermsOfUse" style="width:870px; z-index: 20; overflow:auto;">
    <div id="divCloser" style="position:relative; left: 852px;">
        <div style="position:fixed; z-index:22;">
            <a href="javascript:hideDiv('divTermsOfUse');">
                <span style="font-size:18pt; font-weight:bold;">X</span>
            </a>
        </div>
    </div>
    <div>  <!-- container for... -->
         lots of Text To Be Scrolled vertically...
         bhah! blah! blah!
    </div>
</div>

Ci-dessus m'a permis de localiser un bouton de fermeture "X" en haut de beaucoup de texte dans un div avec défilement vertical. Le "X" se place en place (ne se déplace pas avec le texte défilé et pourtant il se déplace vers la gauche ou la droite avec le conteneur div englobant lorsque l'utilisateur redimensionne la largeur de la fenêtre du navigateur! Ainsi, il est "fixe" verticalement, mais positionné par rapport à l'élément enveloppant horizontalement!

Avant que cela ne fonctionne, le "X" a défilé vers le haut et hors de vue lorsque j'ai fait défiler le contenu du texte vers le bas.

Toutes mes excuses pour ne pas avoir fourni ma fonction javascript hideDiv (), mais cela rendrait ce message inutilement plus long. J'ai choisi de le garder aussi court que possible.

Bruce Allen
la source
Solution multi-navigateur solide, fonctionne dans IE8 comme un charme.
dmi3y
1

J'ai créé un jsfiddle pour montrer comment cela fonctionne en utilisant la transformation.

HTML

<div class="left">
    Content
</div>
<div class="right">
<div class="fixedContainer">
    X
</div>
    Side bar
</div>

CSS

body {
  margin: 0;
}
.left {
  width: 77%;
  background: teal;
  height: 2000px;
}
.right {
  width: 23%;
  background: yellow;
  height: 100vh;
  position: fixed;
  right: 0;
  top: 0;
}
.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    //right: 0;
    top: 0%;
    transform: translateX(-100px);
}

jQuery

$('.fixedContainer').on('click', function() {
    $('.right').animate({'width': '0px'});
  $('.left').animate({'width': '100%'});
});

https://jsfiddle.net/bx6ktwnn/1/

Loupe
la source
1

J'ai le même problème, l'un des membres de notre équipe me donne une solution. Pour autoriser la position de fix div et par rapport aux autres div, notre solution est d'utiliser un conteneur père enveloppant le div fixe et le div de défilement.

<div class="container">
  <div class="scroll"></div>
  <div class="fix"></div>
</div>

css

.container {
  position: relative;
  flex:1;
  display:flex;
}

.fix {
  prosition:absolute;
}
Jay0Lu
la source
1
/* html */

/* this div exists purely for the purpose of positioning the fixed div it contains */
<div class="fix-my-fixed-div-to-its-parent-not-the-body">

     <div class="im-fixed-within-my-container-div-zone">
          my fixed content
     </div>

</div>



/* css */

/* wraps fixed div to get desired fixed outcome */
.fix-my-fixed-div-to-its-parent-not-the-body 
{
    float: right;
}

.im-fixed-within-my-container-div-zone
{
    position: fixed;
    transform: translate(-100%);
}
Carol McKay
la source
1

Oui, c'est possible tant que vous ne définissez pas la position ( topou left, etc.) de votre fixedélément (vous pouvez toujours utiliser marginpour définir une position relative, cependant). Simon Bos a publié un article à ce sujet il y a quelque temps .

Cependant, ne vous attendez pas à ce que l'élément fixe défile avec des parents non fixes.

Voir une démo ici .

Javarome
la source
0

J'ai fait quelque chose comme ça il y a quelque temps. J'étais assez nouveau sur JavaScript, donc je suis sûr que vous pouvez faire mieux, mais voici un point de départ:

function fixxedtext() {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        if (document.body.offsetWidth > 960) {
            var width = document.body.offsetWidth - 960;
            width = width / 2;
            document.getElementById("side").style.marginRight = width + "px";
        }
        if (document.body.offsetWidth < 960) {
            var width = 960 - document.body.offsetWidth;
            document.getElementById("side").style.marginRight = "-" + width + "px";
        }
    }
    else {
        if (window.innerWidth > 960) {
            var width = window.innerWidth - 960;
            width = width / 2;
            document.getElementById("side").style.marginRight = width + "px";
        }
        if (window.innerWidth < 960) {
            var width = 960 - window.innerWidth;
            document.getElementById("side").style.marginRight = "-" + width + "px";
        }
    }
    window.setTimeout("fixxedtext()", 2500)
}

Vous devrez définir votre largeur, puis il obtient la largeur de la fenêtre et modifie la marge toutes les quelques secondes. Je sais que c'est lourd, mais ça marche.

webLacky3rdClass
la source
un problème que je peux voir avec cette approche est qu'elle repose sur un minuteur (2,5 secondes) et pendant ce temps, si l'utilisateur redimensionne la fenêtre, il lui faudra jusqu'à ce temps pour se corriger. Ce n'est pas la meilleure chose en termes d'expérience utilisateur. De plus, si cela peut être aidé, essayez d'utiliser des écouteurs d'événements au lieu de minuteries.
Joseph Marikle
Comme je l'ai dit, c'était un VIEUX script, l'un de mes premiers, et je n'ai pas eu besoin de revenir en arrière pour le réparer. Ce n'est donc pas le meilleur, mais cela peut être un bon point de départ.
webLacky3rdClass
0

C'est possible si vous utilisez JavaScript. Dans ce cas, le plugin jQuery Sticky-Kit :

Paz Aricha
la source
0

Mon projet est le modèle .NET ASP Core 2 MVC Angular 4 avec Bootstrap 4. L'ajout de "sticky-top" dans le composant principal de l'application html (c'est-à-dire app.component.html) sur la première ligne a fonctionné, comme suit:

<div class='row sticky-top'>
    <div class='col-sm-12'>
        <nav-menu-top></nav-menu-top>
    </div>
</div>
<div class="row">
    <div class='col-sm-3'>
        <nav-menu></nav-menu>
    </div>
    <div class='col-sm-9 body-content'>
        <router-outlet></router-outlet>
    </div>
</div>

Est-ce la convention ou ai-je trop simplifié cela?

Adam Cox
la source
0

Lorsque vous utilisez la position:fixedrègle CSS et essayez d'appliquer top/ left/ right/ bottomil positionne l'élément par rapport à la fenêtre.

Une solution de contournement consiste à utiliser des marginpropriétés au lieu de top/ left/ right/bottom

Sunil Garg
la source
-1

Vérifiez ça:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
    <body style="width: 1000px !important;margin-left: auto;margin-right: auto">
        <div style="width: 100px; height: 100px; background-color: #ccc; position:fixed;">
        </div>
        <div id="1" style="width: 100%; height: 600px; background-color: #800000">
        </div>
        <div id="2" style="width: 100%; height: 600px; background-color: #100000">
        </div>
        <div id="3" style="width: 100%; height: 600px; background-color: #400000">
        </div>
    </body>
</html>
Kunal
la source
5
Je ne pense pas que cela accomplisse exactement ce que le PO a demandé.
JasonWyatt