Existe-t-il un moyen d'élargir la largeur d'un DIV enfant par rapport au DIV parent en utilisant CSS?


229

Existe-t-il un moyen d'avoir un DIV enfant dans un conteneur parent DIV qui est plus large que son parent. Le DIV enfant doit avoir la même largeur que la fenêtre du navigateur.

Voir l'exemple ci-dessous: entrez la description de l'image ici

L'enfant DIV doit rester comme un enfant de la parent div. Je sais que je peux définir des marges négatives arbitraires sur le div enfant pour le rendre plus large, mais je ne peux pas trouver comment le rendre essentiellement à 100% de la largeur du navigateur.

Je sais que je peux le faire:

.child-div{
    margin-left: -100px;
    margin-right: -100px;
}

Mais j'ai besoin que l'enfant ait la même largeur que le navigateur qui est dynamique.

Mettre à jour

Merci pour vos réponses, il semble que la réponse la plus proche à ce jour soit de rendre la position DIV de l'enfant: absolue et de définir les propriétés gauche et droite sur 0.

Le problème suivant que j'ai est que le parent a la position: relative, ce qui signifie que les propriétés gauche et droite sont toujours relatives au div parent et non au navigateur, voir l'exemple ici: jsfiddle.net/v2Tja/2

Je ne peux pas supprimer la position relative du parent sans tout gâcher.


Vos exigences n'ont pas vraiment de sens. Le "div enfant" doit rester comme un enfant du div parent, et pourtant le div parent a position: relative? De quoi avez-vous besoin position: relative? Je suppose que ce que je demande, c'est: qu'essayez-vous de faire?
thirtydot

@Camsoft Avez-vous vu mon commentaire sur ma réponse? Cela fonctionne pour moi, consultez également mon site Web edocuments.co.uk qui fait ce que vous essayez de faire d'une manière différente
Blowsie

1
@Camsoft en plus, il ne devrait vraiment pas y avoir besoin de jquery / js dans votre solution
Blowsie

Réponses:


112

Utiliser un positionnement absolu

.child-div {
    position:absolute;
    left:0;
    right:0;
}

14
Ok, question suivante, que se passe-t-il si le parent ou un autre ancêtre a la disposition, c'est-à-dire la position: relative, voir: jsfiddle.net/v2Tja/2
Camsoft

que diriez-vous d'un autre parent div étant position: statique, et un autre div à l'intérieur avec position: relative? jsfiddle.net/blowsie/v2Tja/3
Blowsie

10
existe-t-il un moyen de le faire, avec la hauteur automatique de .child-div et toujours le placement correct ci-dessous?
Philippe Gilbert

2
et ne définissez pas le div parent sur "overflow: hidden" ^^
chris

@Blowsie que diriez-vous position:fixed . pourquoi cela ne fonctionne pas correctement?
Mostafa Ghadimi du

227

Voici une solution générique qui conserve l'élément enfant dans le flux de documents:

.child {
  width: 100vw;
  position: relative;
  left: calc(-50vw + 50%);
}

Nous définissons l' widthélément enfant pour qu'il remplisse toute la largeur de la fenêtre d'affichage, puis nous le faisons correspondre au bord de l'écran en le déplaçant vers leleft une distance de la moitié de la fenêtre, moins 50% de la largeur de l'élément parent.

Démo:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  overflow-x: hidden;
}

.parent {
  max-width: 400px;
  margin: 0 auto;
  padding: 1rem;
  position: relative;
  background-color: darkgrey;
}

.child {
  width: 100vw;
  position: relative;
  left: calc(-50vw + 50%);

  height: 100px;
  border: 3px solid red;
  background-color: lightgrey;
}
<div class="parent">
  Pre
  <div class="child">Child</div>
  Post
</div>

Le support du navigateur pour vw et pour calc () peut généralement être vu comme IE9 et plus récent.

Remarque: Cela suppose que le modèle de boîte est défini sur border-box. Sans border-box, vous devrez également soustraire les rembourrages et les bordures, ce qui rend cette solution un gâchis.

Remarque: Il est recommandé de masquer le débordement horizontal de votre conteneur de défilement, car certains navigateurs peuvent choisir d'afficher une barre de défilement horizontale malgré l'absence de débordement.


4
Que savez-vous, cela fonctionne en effet dans IE9. +1 Nice
CatShoes

13
C'était exactement ce que je cherchais merci très mutch. OMI, c'est une meilleure réponse que celle acceptée car celle-ci ne rompt pas le flux de documents
Rémi

18
vw n'est pas bon. Si vous avez une barre de défilement verticale, 100vw vous donnera une barre de défilement horizontale.
Sunny

2
Il semble que cela ne fonctionne que d'un niveau plus bas. Existe-t-il un moyen de le faire fonctionner quel que soit le nombre d'éléments parents d'un élément enfant?
mythofechelon

3
C'est la bonne réponse pour envelopper un élément enfant plus large dans un position: relativeparent!
Hanfei Sun

14

J'ai longtemps cherché une solution à ce problème. Idéalement, nous voulons que l'enfant soit plus grand que le parent, mais sans connaître à l'avance les contraintes du parent.

Et j'ai finalement trouvé une brillante réponse générique ici . Copier mot pour mot:

L'idée ici est de: pousser le conteneur au milieu exact de la fenêtre du navigateur avec la gauche: 50%; puis le tirer vers le bord gauche avec une marge négative de -50vw.

.child-div {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
}

1
J'ai trouvé que si je veux que ce soit, disons, 90% de la largeur de la fenêtre, je peux utiliser la valeur ci-dessus mais définir la largeur sur 90vw. Il semble également que cela margin-rightn'ait aucun effet dans tous les cas.
Jason Dufair

a dû changer les valeurs margin-left et right car mon wrapper représente 80% de la largeur de la fenêtre d'affichage. Donc dans mon cas, il fallait que ce soit margin-left: -10vw et margin-right: -10vw et puis ça a parfaitement fonctionné! Merci!
Timotheus Triebl

1
C'était une brillante réponse! Merci.
cullanrocks du

7

Sur la base de votre suggestion d'origine (définition de marges négatives), j'ai essayé et trouvé une méthode similaire en utilisant des unités de pourcentage pour la largeur du navigateur dynamique:

HTML

<div class="grandparent">
    <div class="parent">
        <div class="child">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolore neque repellat ipsum natus magni soluta explicabo architecto, molestias laboriosam rerum. Tempore eos labore temporibus alias necessitatibus illum enim, est harum perspiciatis, sit, totam earum corrupti placeat architecto aut minus dignissimos mollitia asperiores sint ea. Libero hic laudantium, ipsam nostrum earum distinctio. Cum expedita, ratione, accusamus dicta similique distinctio est dolore assumenda soluta dolorem quisquam ex possimus aliquid provident quo? Enim tempora quo cupiditate eveniet aperiam.</p>
        </div>
    </div>
</div>

CSS:

.child-div{
   margin: 0 -100%;
   padding: 0 -100%;
}

.parent {
    width: 60%;
    background-color: red;
    margin: 0 auto;
    padding: 50px;
    position:relative;
}

.grandparent {
        overflow-x:hidden;
        background-color: blue;
        width: 100%;
        position:relative;
    }

Les marges négatives laisseront le contenu sortir de la DIV parentale. Par conséquent, j'ai défini le padding: 0 100%;pour repousser le contenu aux limites d'origine du Chlid DIV.

Les marges négatives entraîneront également l'expansion de la largeur totale du .child-div hors de la fenêtre du navigateur, entraînant un défilement horizontal. Par conséquent, nous devons couper la largeur d'extrusion en appliquant un overflow-x: hiddenà un grand-parent DIV (qui est le parent du parent Div):

Voici le JSfiddle

J'ai essayé Nils Kaspersson left: calc(-50vw + 50%) ; cela a parfaitement fonctionné dans Chrome et FF (pas encore sûr d'IE) jusqu'à ce que je découvre que les navigateurs Safari ne le font pas correctement. J'espère qu'ils ont corrigé cela dès que j'aime vraiment cette méthode simple.

Cela peut également résoudre votre problème où l'élément parent DIV doit être position:relative

Les 2 inconvénients de cette méthode de contournement sont:

  • Exiger un balisage supplémentaire (c'est-à-dire un élément grand-parent (tout comme la bonne méthode d'alignement vertical de la bonne vieille table n'est-ce pas ...)
  • Les bordures gauche et droite de la DIV enfant ne s'afficheront jamais, simplement parce qu'elles sont en dehors de la fenêtre d'affichage du navigateur.

Veuillez me faire savoir s'il y a un problème avec cette méthode;). J'espère que ça aide.


4

Flexbox peut être utilisé pour rendre un enfant plus large que son parent avec trois lignes de CSS.

Seul l'enfant display, margin-leftet widthdoit être réglé. margin-leftdépend de l'enfant width. La formule est:

margin-left: calc(-.5 * var(--child-width) + 50%);

Les variables CSS peuvent être utilisées pour éviter de calculer manuellement la marge gauche.

Démo # 1: Calcul manuel

.parent {
  background-color: aqua;
  height: 50vh;
  margin-left: auto;
  margin-right: auto;
  width: 50vw;
}

.child {
  background-color: pink;
  display: flex;
}

.wide {
  margin-left: calc(-37.5vw + 50%);
  width: 75vw;
}

.full {
  margin-left: calc(-50vw + 50%);
  width: 100vw;
}
<div class="parent">
  <div>
    parent
  </div>
  <div class="child wide">
    75vw
  </div>
  <div class="child full">
    100vw
  </div>
</div>

Démo # 2: Utilisation de variables CSS

.parent {
  background-color: aqua;
  height: 50vh;
  margin-left: auto;
  margin-right: auto;
  width: 50vw;
}

.child {
  background-color: pink;
  display: flex;
  margin-left: calc(-.5 * var(--child-width) + 50%);
  width: var(--child-width);
}

.wide {
  --child-width: 75vw;
}

.full {
  --child-width: 100vw;
}
<div class="parent">
  <div>
    parent
  </div>
  <div class="child wide">
    75vw
  </div>
  <div class="child full">
    100vw
  </div>
</div>


3

J'ai utilisé ceci:

HTML

<div class="container">
 <div class="parent">
  <div class="child">
   <div class="inner-container"></div>
  </div>
 </div>
</div>

CSS

.container {
  overflow-x: hidden;
}

.child {
  position: relative;
  width: 200%;
  left: -50%;
}

.inner-container{
  max-width: 1179px;
  margin:0 auto;
}

1

vous pouvez essayer la position: absolue. et donnez la largeur et la hauteur, en haut: 'axe y à partir du haut' et à gauche: 'axe x'


1

J'ai eu un problème similaire. Le contenu de l'élément enfant devait rester dans l'élément parent tandis que l'arrière-plan devait étendre toute la largeur de la fenêtre.

J'ai résolu ce problème en créant l'élément enfant position: relativeet en lui ajoutant un pseudo-élément ( :before) avec position: absolute; top: 0; bottom: 0; width: 4000px; left: -1000px;. Le pseudo-élément reste derrière l'enfant réel en tant que pseudo-élément d'arrière-plan. Cela fonctionne dans tous les navigateurs (même IE8 + et Safari 6+ - n'ont pas la possibilité de tester des versions plus anciennes).

Petit exemple de violon: http://jsfiddle.net/vccv39j9/


Cela semble fonctionner, mais cela amène le navigateur à afficher une barre de défilement horizontale puisque la largeur est de 4000 pixels. Quelle est la solution de contournement pour conserver le pseudo-élément dans la largeur de la fenêtre?
Aaron Hudon

Bien sûr, vous devez définir le corps ou la div d'habillage de page sur overflow-x: hidden.
Seika85

1

En ajoutant à la solution de Nils Kaspersson, je résout également la largeur de la barre de défilement verticale. J'utilise 16pxcomme exemple, qui est soustrait de la largeur du port de vue. Cela évitera l'apparition de la barre de défilement horizontale.

width: calc(100vw - 16px);
left: calc(-1 * (((100vw - 16px) - 100%) / 2));

1
Je crois que ce 16pxque vous devez soustraire car il provoque la barre de défilement horizontale est la marge / remplissage par défaut du navigateur, au lieu de le soustraire, utilisez-le simplement html, body{ margin:0; padding:0 }ainsi vous n'aurez pas besoin de faire de calcul supplémentaire pour le16px
Mi-Creativity

C'est lorsque le contenu de la page est plus long et passe en dessous du pli et que la barre de défilement apparaît automatiquement. Bien sûr, lorsque le contenu est dans le giron, cela n'est pas nécessaire. J'ajoute le 16px à la formule uniquement lorsque je sais que le contenu de la page sera long et que la barre de défilement apparaîtra en effet.
A-Zone

je pense que cela ne fonctionnera pas sur mobile. le mobile n'a pas de barre de défilement.
hjchin

1

En supposant que le parent a une largeur fixe, par exemple #page { width: 1000px; }et qu'il est centré #page { margin: auto; }, vous voulez que l'enfant s'adapte à la largeur de la fenêtre du navigateur que vous pouvez simplement faire:

#page {
    margin: auto;
    width: 1000px;
}

.fullwidth {
    margin-left: calc(500px - 50vw); /* 500px is half of the parent's 1000px */
    width: 100vw;
}

1

Pour rendre la division enfant aussi large que le contenu, essayez ceci:

.child{
    position:absolute;
    left:0;
    overflow:visible;
    white-space:nowrap;
}

0
.parent {
    margin:0 auto;
    width:700px;
    border:2px solid red;
}
.child {
    position:absolute;
    width:100%;
    border:2px solid blue;
    left:0;
    top:200px;
}

Intelligent, mais ne semble pas fonctionner (avec des portées intégrées au moins dans les li).
ruffin

0

Je sais que c'est vieux mais pour quiconque vient à cela pour une réponse, vous le feriez comme ceci:

Débordement masqué sur un élément contenant l'élément parent, tel que le corps.

Donnez à votre élément enfant une largeur beaucoup plus large que votre page et positionnez-le à gauche de -100%.

Voici un exemple:

body {
  overflow:hidden;
}

.parent{
  width: 960px;
  background-color: red;
  margin: 0 auto;
  position: relative;    
}

.child {
  height: 200px;
  position: absolute;
  left: -100%;
  width:9999999px;
}

Voici également un violon JS: http://jsfiddle.net/v2Tja/288/


0

La solution sera alors la suivante.

HTML

<div class="parent">
    <div class="child"></div>
</div>

CSS

.parent{
        width: 960px;
        margin: auto;
        height: 100vh
    }
    .child{
        position: absolute;
        width: 100vw
    }

Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant la manière et / ou la raison pour laquelle il résout le problème améliorerait la valeur à long terme de la réponse.
R Balasubramanian

0

J'ai essayé certaines de vos solutions. Celui-là :

margin: 0px -100%;
padding: 0 100%;

est de loin le meilleur, car nous n'avons pas besoin de CSS supplémentaires pour un écran plus petit. J'ai créé un codePen pour afficher les résultats: j'ai utilisé un div parent avec une image d'arrière-plan et un div div enfant avec un contenu interne.

https://codepen.io/yuyazz/pen/BaoqBBq

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.