Responsive break out of parent element

We cannot solve our problems with the same thinking we used when we created them
Albert Einstein
The problem
Making a child element break out of its parent container is a thing that almost always causes a world of pain, a messy stylesheet and a bad developer-designer relationship.
In general you are left with one of two choices:
- Make the widths larger than 100%, try to counter the wrapping padding and add media queries to fix the negative margins when the content starts to overflow the viewport.
- Target all the nested elements individually (.container > *), create a faux or pseudo-element background on the wrapper and don't forget the media queries.
The Solution
Rather than focusing on the parent and or trying keep track of all the child elements – take the evil wrapper pill and swallow your pride. Visual explanation
<main>
<article>
<h1>Lorem ipsum</h1>
<p>Lorem ipsum dolor sit amet.</p>
<div class="breakout">
<img src="image.jpg" />
</div>
<p>Lorem ipsum dolor sit amet.</p>
</article>
</main>
The wrapper:
/**
* 1 Position the wrapper relative to the parent element
* 2 Make the wrapper fit the content height
* 3 Set the width to match the width of the viewport (100vm)
* 4 Push the wapper to the center of the parent element
*
* Note! Remember to add html,body { overflow-x:hidden; } to
* prevent horizontal scrolling
*
* Note! If the left and right padding of your wrapper are
* not the same – adjust the .breakout margin-left
* breakout-margin-left: (wrapper-padding-right - wrapper-padding-left)/2
*/
.breakout {
position:relative;
display:table;
width:100vw;
left:50%;
}
The content:
/**
* Generic content style
* 1 Position the content relative to the wrapper
* 2 Center the content
* 3 Pull the content -50% to the left and hereby
* back to the center of the page
*/
.breakout > * {
position:relative;
margin-left:auto;
margin-right:auto;
left:-50%;
}
/**
* Custom content style
* Note! min-width will cause cropping
*/
.breakout > img {
display:block;
width:100%;
max-width:960px;
min-width:320px;
}
The bug and the fixes:
Sadly browsers sucks at handling vm units - especially mobile ie6 incarnated (Safari on iOS7)... and once again we have to turn to JavaScript. make workarounds
As of October 19, 2015 91% of iDevices are running iOS8+
Media Query Fix:Benjamin Morel made a mixin to handle viewport units on iOS 7 that produces the following queries:
@media only screen and (-webkit-min-device-pixel-ratio: 1) and (device-width: 768px) and (device-height: 1024px) and (orientation: portrait) {
.breakout { width: 768px; }
}
@media only screen and (-webkit-min-device-pixel-ratio: 1) and (device-width: 768px) and (device-height: 1024px) and (orientation: landscape) {
.breakout { width: 1024px; }
}
@media only screen and (-webkit-min-device-pixel-ratio: 1) and (device-width: 320px) and (device-height: 480px) and (orientation: portrait) {
.breakout { width: 320px; }
}
@media only screen and (-webkit-min-device-pixel-ratio: 1) and (device-width: 320px) and (device-height: 480px) and (orientation: landscape) {
.breakout { width: 480px; }
}
@media only screen and (-webkit-min-device-pixel-ratio: 1) and (device-width: 320px) and (device-height: 568px) and (orientation: portrait) {
.breakout { width: 320px; }
}
@media only screen and (-webkit-min-device-pixel-ratio: 1) and (device-width: 320px) and (device-height: 568px) and (orientation: landscape) {
.breakout { width: 568px; }
}
JavaScript Fix:
<script>
function vwFix(){
var ww = window.innerWidth + 'px';
var el = document.getElementsByClassName('breakout');
for(var i=0,l=el.length;i<l;++i){ el[i].style.width = ww; }
};
vwFix();
window.addEventListener('resize', vwFix);
// ...or if you prefer jQuery
$(window).on('resize',function(){
$('.breakout').width(window.innerWidth);
}).trigger('resize');
</script>
