|
<main> |
|
<article> |
|
<header class="breakout"> |
|
<h1>Responsive break out of parent element</h1> |
|
</header> |
|
|
|
<div class="breakout"> |
|
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/68939/ae.jpg" /> |
|
</div> |
|
|
|
<div class="breakout"> |
|
<blockquote> |
|
<p>We cannot solve our problems with the same thinking we used when we created them</p> |
|
</blockquote> |
|
<p>Albert Einstein</p> |
|
</div> |
|
|
|
<h2>The problem</h2> |
|
<p> |
|
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. |
|
</p> |
|
<p>In general you are left with one of two choices: |
|
<ul> |
|
<li>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. |
|
</li> |
|
<li>Target all the nested elements individually (.container > *), create a faux or pseudo-element background on the wrapper and don't forget the media queries. |
|
</li> |
|
</ul> |
|
</p> |
|
|
|
<h2>The Solution</h2> |
|
<p>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. |
|
</p> |
|
<code> |
|
<main> |
|
<article> |
|
<h1>Lorem ipsum</h1> |
|
<p>Lorem ipsum dolor sit amet.</p> |
|
|
|
<em><div class="breakout"> |
|
<img src="image.jpg" /> |
|
</div></em> |
|
|
|
<p>Lorem ipsum dolor sit amet.</p> |
|
</article> |
|
</main> |
|
</code> |
|
|
|
<strong>The wrapper:</strong> |
|
<code> |
|
/** |
|
* 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 |
|
*/ |
|
.breakout { |
|
position:relative; |
|
display:table; |
|
width:100vm; |
|
left:50%; |
|
} |
|
</code> |
|
<strong>The content:</strong> |
|
<code> |
|
/** |
|
* 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; |
|
} |
|
</code> |
|
|
|
<h2>The bugs and the fix:</h2> |
|
<p>Sadly browsers sucks at handling vm units - especially mobile ie6 incarnated (Safari on iOS7)... and once again we have to turn to JavaScript.</p> |
|
|
|
<strong>The script:</strong> |
|
<code> |
|
<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> |
|
</code> |
|
|
|
<footer class="breakout"> |
|
<p>Please comment :-) <br> |
|
Note! Because of the iframe on codepen this page might not show correctly unless in debug view. </p> |
|
</footer> |
|
</article> |
|
<div class="tools"> |
|
<a href="#" class="trans">CSS Transitions:</a> |
|
<a href="#" class="sizes">Random max-widths</a> |
|
</div> |
|
</main> |
|
|
|
|