Is there are way to make a child DIV's width wider than the parent DIV using CSS?
Solution 1
Use absolute positioning
.child-div {
position:absolute;
left:0;
right:0;
}
Solution 2
Here's a generic solution that keeps the child element in the document flow:
.child {
width: 100vw;
position: relative;
left: calc(-50vw + 50%);
}
We set the width
of the child element to fill the entire viewport width, then we make it meet the edge of the screen by moving it to the left
by a distance of half the viewport, minus 50% of the parent element's width.
Demo:
* {
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>
Browser support for vw and for calc() can generally be seen as IE9 and newer.
Note: This assumes the box model is set to border-box
. Without border-box
, you would also have to subtract paddings and borders, making this solution a mess.
Note: It is encouraged to hide horizontal overflow of your scrolling container, as certain browsers may choose to display a horizontal scrollbar despite there being no overflow.
Solution 3
I've searched far and wide for a solution to this problem for a long time. Ideally we want to have the child greater than the parent, but without knowing the constraints of the parent in advance.
And I finally found a brilliant generic answer here. Copying it verbatim:
The idea here is: push the container to the exact middle of the browser window with left: 50%;, then pull it back to the left edge with negative -50vw margin.
.child-div {
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
}
Solution 4
Based on your suggestion original suggestion (setting negative margins), I have tried and come up with a similar method using percentage units for dynamic browser width:
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;
}
The negative margins will let the content flow out of the Parent DIV. Therefore I set the padding: 0 100%;
to push the content back to the original boundaries of the Chlid DIV.
The negative margins will also make the .child-div's total width expands out of the browser's viewport, resulting in a horizontal scroll. Hence we need to clip the extruding width by applying an overflow-x: hidden
to a Grandparent DIV (which is the parent of the Parent Div):
Here is the JSfiddle
I haved tried Nils Kaspersson's left: calc(-50vw + 50%)
; it worked perfectly fine in Chrome & FF (not sure about IE yet) until I found out Safari browsers doesn't do it properly. Hope they fixed this soon as I actually like this simple method.
This also may resolve your issue where the Parent DIV element has to be position:relative
The 2 drawbacks of this workaround method is:
- Require extra markup (i.e a grandparent element (just like the good ol' table vertical align method isn't it...)
- The left and right border of the Child DIV will never show, simply because they are outside of the browser's viewport.
Please let me know if there's any issue you find with this method ;). Hope it helps.
Solution 5
Flexbox can be used to make a child wider than its parent with three lines of CSS.
Only the child’s display
, margin-left
and width
need to be set. margin-left
depends on the child’s width
. The formula is:
margin-left: calc(-.5 * var(--child-width) + 50%);
CSS variables can be used to avoid manually calculating the left margin.
Demo #1: Manual calculation
.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>
Demo #2: Using CSS variables
.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>
Related videos on Youtube
Camsoft
Updated on May 16, 2020Comments
-
Camsoft almost 4 years
Is there a way to have a child DIV within a parent container DIV that is wider than it's parent. The child DIV needs to be the same width of the browser viewport.
See example below:
The child DIV must stay as a child of the parent div. I know I can set arbitrary negative margins on the child div to make it wider but I can't work out how to essentially make it 100% width of the browser.
I know I can do this:
.child-div{ margin-left: -100px; margin-right: -100px; }
But I need the child to be the same width as the browser which is dynamic.
Update
Thanks for your answers, it seems the closest answer so far is to make the child DIV position: absolute, and set the left and right properties to 0.
The next problem I have is that the parent has position: relative, which means that left and right properties are still relative to the parent div and not the browser, see example here: jsfiddle.net/v2Tja/2
I can't remove the position relative from the parent without screwing everything else up.
-
Blowsie about 13 years@Camsoft in addition , there really should be no need for any jquery / js in your solution
-
-
Camsoft about 13 yearsOk, next question, what if the parent or another ancestor has layout i.e. position: relative, see: jsfiddle.net/v2Tja/2
-
Blowsie about 13 yearshow about another parent div being position:static, and another div inside with position:relative? jsfiddle.net/blowsie/v2Tja/3
-
Philippe Gilbert about 11 yearsis there a way to do this, whith the .child-div's height auto and still have the correct placement below?
-
chris over 10 yearsand don't set the parent div to "overflow:hidden" ^^
-
CatShoes over 9 yearsWhat do you know, it does indeed work in IE9. +1 Nice
-
Rémi over 9 yearsThis was exactly what I was looking for thank you very mutch. IMO this is a better answer than the accepted one since this one doesn't break document flow
-
Sunny about 9 yearsvw is no good. If you have a vertical scrollbar then 100vw will give you a horizontal scrollbar.
-
mythofechelon over 8 yearsIt seems that this only works one level down. Is there a way for it to work regardless of how many parent elements a child element has?
-
mythofechelon over 8 years@Nils Kaspersson Awesome, thank you again! Tip: Squarespace uses the LESS compiler so
left: calc(~"-50vw + 50%");
must be used or it will be translated intoleft: calc(0vw);
-
Hanfei Sun over 8 yearsThis is the right answer to wrap wider child element into a
position: relative
parent! -
Merchako about 8 yearsHow does this appear when degraded by older browsers?
-
Nils Kaspersson about 8 years@Merchako Invalid/unknown values invalidate the entire property declaration, so browsers that don't support
vw
will ignore both rules. Remove thewidth
andleft
declaration to see what it would look like. If a browser supportsvw
but doesn't supportcalc()
then you'll get an unwantedleft
-assignment. Use feature detection to set the rules if you need to support such a browser. -
Jason Dufair over 6 yearsI found if I want it to be, say, 90% of the viewport width, I can use the above but set width to
90vw
. Also, it appears thatmargin-right
has no effect in any case. -
R Balasubramanian over 5 yearsWhile this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.
-
typo about 5 yearsA simple
margin-left: calc(...);
does the same thing as theposition: relative;
&left calc(...);
combo. Is there some reasonposition: relative;
is a better choice? -
Nils Kaspersson about 5 years@typo
margin
theoretically affects surrounding elements whereasleft
does not. Chances are you can achieve the exact same result withmargin
, I just prefer using the most correct property. -
DanielSon almost 5 years@mythofechelon same for xf as well - wondering why it was glitching, but your modification for less solved it. Many thanks!
-
Mostafa Ghadimi almost 5 years@Blowsie how about
position:fixed
. why it doesn't work properly? -
Timotheus0106 almost 5 yearshad to change the margin-left and right values cause my wrapper is 80% of viewport width. So in my case it had to be margin-left:-10vw and margin-right:-10vw and then it perfectly worked! thanks!
-
cullanrocks over 4 yearsThis was a brilliant answer! Thanks.
-
Saunved Mutalik almost 3 yearsThis is a really clever answer and works well!
-
OutlawSloth over 2 yearsno, if you use position:absolute, the content will be placed on top of everything else on your application, which is awful!! Nils Kasperssons answer is the right way!!
-
BrunoElo about 2 yearsI guess
overflow: overlay
can be added to the parent to remove horizontal scrollbar