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.

Camsoft
la source
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;
}
Blowsie
la source
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.

Nils Kaspersson
la source
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;
}
dangom
la source
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.

Austeroid
la source
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>

Markus
la source
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;
}
hsuastegui
la source
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'

Khurram Ijaz
la source
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/

Seika85
la source
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));
A-Zone
la source
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;
}
Nabil Kadimi
la source
1

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

.child{
    position:absolute;
    left:0;
    overflow:visible;
    white-space:nowrap;
}
Toki
la source
0
.parent {
    margin:0 auto;
    width:700px;
    border:2px solid red;
}
.child {
    position:absolute;
    width:100%;
    border:2px solid blue;
    left:0;
    top:200px;
}
Sam
la source
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/

Tom Chinery
la source
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
    }
Himavan
la source
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

blogob
la source