PageSourceSearch

https://christianalfoni.github.io/css/2013/06/23/css:-stretching-correctly-with-100%25.html

html christianalfoni.github.io collected 2026-10-03 08:47:41 UTC 20,876 bytes, 288 lines download raw bytes

1<!DOCTYPE html>
2<html>
3<head>
4    <title>christianalfoni WebApp Enthusiast</title>
5    <meta charset="utf-8">
6    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
7    <title>CSS: Stretching correctly with 100%</title>
8    <meta name="viewport"
9          content="width=device-width, user-scalable=0, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
10    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
11    <meta name="msapplication-tap-highlight" content="no"/>
12    <meta name="apple-mobile-web-app-capable" content="yes">
13
14      <link href='http://fonts.googleapis.com/css?family=Inconsolata:400,700' rel='stylesheet' type='text/css'>
15    <!-- syntax highlighting CSS -->
16    <link rel="stylesheet" href="/css/syntax.css">
17
18    <!-- Custom CSS -->
19    <link rel="stylesheet" href="/css/main.css">
20  
21    
21<script>
vendor: 377 bytes, lines 21-27
21
22    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
23      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
24      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
25                            })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
26
27    ga('create', '
27UA-53419566-1
vendor: 43 bytes, lines 27-30
27', 'auto');
28    ga('send', 'pageview');
29
30  
30</script>
30
31
32</head>
33<body>
34
35<script type="text/javascript">
36    WebFontConfig = {
37        google: { families: [ 'Alegreya+Sans::latin' ] }
38    };
39    (function () {
40        var wf = document.createElement('script');
41        wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
42                '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
43        wf.type = 'text/javascript';
44        wf.async = 'true';
45        wf.onload = function () {
46            setTimeout(function () {
47                document.body.querySelector('.site').style.display = 'block';
48            }, 100);
49        }
50        var s = document.getElementsByTagName('script')[0];
51        s.parentNode.insertBefore(wf, s);
52    })();
53</script>
53
54
55<div class="site">
56<div style="height: 100px;line-height:100px;background-color:red;color: #FFF;text-align:center;font-size: 32px;font-weight:bold;">
57  The new blog is now available at <a style="color: #FFF;text-decoration: underline;" href="http://www.christianalfoni.com">www.christianalfoni.com</a>
58</div>
59    <div class="background-gradient"></div>
60    <div class="header">
61        <div class="header-top"></div>
62        <div class="header-ribbon" onclick="location.href = '/'"><h1 class="title">christianalfoni</h1></div>
63        <div class="header-bottom"></div>
64    </div>
65
66    <div class="content">
67        <h1 class="quote">Full stack web application <i>enthusiast</i>, running the web standards marathon</h1>
68
69          <center><a href="https://twitter.com/share" class="twitter-share-button" data-text="Check out..." data-via="christianalfoni" data-size="large">Tweet</a>
70        <a href="http://christianalfoni.github.io/feed.xml"><img src="http://www.vienna-rss.org/wp-content/themes/optimize/images/ico-rss.png"/></a>
71      </center>
72<p class="meta">23 Jun 2013</p>
73<h2>CSS: Stretching correctly with 100%</h2>
74
75      
76<div class="post">
77<p>I wish there was a value to width and height of CSS which indicated that the element should use the rest of the space available within its parent element. Something like:</p>
78
79<div class="highlight"><pre><code class="language-css" data-lang="css"><span class="nc">.parent</span> <span class="p">{</span>
80        <span class="k">height</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span>
81        <span class="k">padding-top</span><span class="o">:</span> <span class="m">50px</span><span class="p">;</span>
82    <span class="p">}</span>
83
84    <span class="nc">.parent</span> <span class="nc">.child</span> <span class="p">{</span>
85        <span class="k">height</span><span class="o">:</span> <span class="n">stretch</span><span class="p">;</span>
86    <span class="p">}</span></code></pre></div>
87
88<p>To my experience you more often want your element to stretch out on the remaining space of its parent, rather than use its full height/width. To explain this in more detail,
89think of the following scenario… which actually is a scenario in one of our projects.</p>
90
91<p>We want an interface with modules. We want a fixed height on both the top bar and the bottom bar of the application. The middle section, containing the modules should “stretch”
92based on the height of the browser window.</p>
93
94<p><img src="/assets/img/stretch.jpg" alt="Alt text"></p>
95
96<p>So lets look at the problem step by step. I first insert three divs which represents the top, the content container for the modules and the bottom.</p>
97
98<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;bar-top&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
99    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;content-modules&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
100    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;bar-bottom&quot;</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div>
101
102<p>Looking at the css we first set the <strong>html-</strong> and <strong>body</strong> element to <strong>height: 100%</strong> to stretch it to the height of the window in the browser. Then we set fixed heights for the top and bottom.
103Since there is no <strong>stretch</strong> value for height, we try to insert <strong>100%</strong> on our <strong>content-modules</strong> element. The <strong>auto</strong> value only makes the height fit its content, which is not what we want.</p>
104
105<div class="highlight"><pre><code class="language-css" data-lang="css"><span class="nt">html</span><span class="o">,</span> <span class="nt">body</span> <span class="p">{</span>
106        <span class="k">height</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span>
107        <span class="k">margin</span><span class="o">:</span> <span class="m">0</span><span class="p">;</span>
108    <span class="p">}</span>
109    <span class="nf">#bar-top</span><span class="o">,</span> <span class="nf">#bar-bottom</span> <span class="p">{</span>
110        <span class="k">height</span><span class="o">:</span> <span class="m">60px</span><span class="p">;</span>
111    <span class="p">}</span>
112    <span class="nf">#content-modules</span> <span class="p">{</span>
113        <span class="k">height</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span>
114    <span class="p">}</span></code></pre></div>
115
116<p>What happens now is that the content-modules element will use the height of its parent. So in a scenario where the height of the body is 1000 pixels,
117the height of the <strong>content-modules</strong> element would also be 1000 pixels, causing the total height of the interface to be 1000 pixel + 60 pixels (<strong>bar-top</strong>) +
11860 pixels (<strong>bar-bottom</strong>) = 1120 pixels. Your bottom element will now go outside the window of the browser.</p>
119
120<p><img src="/assets/img/stretch2.jpg" alt="Alt text"></p>
121
122<p>To avoid this we have to think differently. There are probably multiple solutions to this, but this is how I think about it to avoid the problem. This is the mindset:</p>
123
124<ol>
125<li>Elements with child elements that are absolute, must be <strong>position: relative</strong></li>
126<li>Define the available stretch-able space by using padding on the parent element</li>
127<li>Use <strong>box-sizing: border-box</strong> on the parent element to subtract the padding and border defined when child element sets height 100%. This will
128cause child elements to use the actual free space of the parent when using <strong>height: 100%</strong></li>
129<li>All containers with a fixed height should be <strong>position: absolute</strong> and with <strong>top</strong> or <strong>bottom</strong> position defined</li>
130</ol>
131
132<p>So lets see these principles in practice. First we define the CSS:</p>
133
134<div class="highlight"><pre><code class="language-css" data-lang="css"><span class="nt">html</span><span class="o">,</span> <span class="nt">body</span> <span class="p">{</span>
135        <span class="k">height</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span>
136    <span class="p">}</span>
137
138    <span class="nt">body</span> <span class="p">{</span>
139        <span class="k">position</span><span class="o">:</span> <span class="k">relative</span><span class="p">;</span> <span class="c">/* 1. Position relative because of absolute child elements */</span>
140        <span class="k">padding</span><span class="o">:</span> <span class="m">60px</span> <span class="m">0</span> <span class="m">60px</span> <span class="m">0</span><span class="p">;</span> <span class="c">/* 2. Using padding to define strech-able space */</span>
141        <span class="n">box</span><span class="o">-</span><span class="n">sizing</span><span class="o">:</span> <span class="k">border</span><span class="o">-</span><span class="n">box</span><span class="p">;</span> <span class="c">/* 3. Box sizing to subtract padding and border from the 100% height of this element when child elements define 100% height */</span>
142    <span class="p">}</span>
143
144    <span class="nf">#bar-top</span><span class="o">,</span> <span class="nf">#bar-bottom</span> <span class="p">{</span>
145        <span class="k">height</span><span class="o">:</span> <span class="m">60px</span><span class="p">;</span>
146        <span class="k">position</span><span class="o">:</span> <span class="k">absolute</span><span class="p">;</span> <span class="c">/* 4. Setting fixed height elements to absolute */</span>
147        <span class="k">width</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span> <span class="c">/* When absolute a width has to be defined */</span>
148    <span class="p">}</span>
149
150    <span class="nf">#bar-top</span> <span class="p">{</span>
151        <span class="k">top</span><span class="o">:</span> <span class="m">0</span><span class="p">;</span> <span class="c">/* Position absolute top bar */</span>
152    <span class="p">}</span>
153
154    <span class="nf">#bar-bottom</span> <span class="p">{</span>
155        <span class="k">bottom</span><span class="o">:</span> <span class="m">0</span><span class="p">;</span> <span class="c">/* Position absolute bottom bar */</span>
156    <span class="p">}</span>
157
158    <span class="nf">#content-modules</span> <span class="p">{</span>
159        <span class="k">height</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span> <span class="c">/* 100% now refers to the remaining space of the parent after padding and borders are set */</span>
160    <span class="p">}</span></code></pre></div>
161
162<p>This will leave us with the following result.</p>
163
164<p><img src="/assets/img/stretch3.jpg" alt="Alt text"></p>
165
166<p>Lets add some modules.</p>
167
168<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;bar-top&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
169    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;content-modules&quot;</span><span class="nt">&gt;</span>
170        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;module&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
171        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;module&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
172        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;module&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
173    <span class="nt">&lt;/div&gt;</span>
174    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;bar-bottom&quot;</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div>
175
176<p>And the css, safely using 100% height:</p>
177
178<div class="highlight"><pre><code class="language-css" data-lang="css"><span class="nc">.module</span> <span class="p">{</span>
179        <span class="k">height</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span>
180        <span class="k">width</span><span class="o">:</span> <span class="m">250px</span><span class="p">;</span>
181        <span class="k">margin</span><span class="o">:</span> <span class="m">0</span> <span class="m">20px</span><span class="p">;</span>
182    <span class="p">}</span></code></pre></div>
183
184<p><img src="/assets/img/stretch4.jpg" alt="Alt text"></p>
185
186<p>As we can see we are not quite there yet. The modules are attached to the top and bottom bar, we want some spacing between modules and the bars.
187You might think that margins are a good idea, but that will increase the total height of our modules. When using the concept explained here,
188tell yourself: <strong>“The stretch-area is defined by the padding of the parent”</strong>, so lets see what we can do there.</p>
189
190<div class="highlight"><pre><code class="language-css" data-lang="css"><span class="nt">body</span> <span class="p">{</span>
191        <span class="k">position</span><span class="o">:</span> <span class="k">relative</span><span class="p">;</span>
192        <span class="k">padding</span><span class="o">:</span> <span class="m">70px</span> <span class="m">0</span> <span class="m">70px</span> <span class="m">0</span><span class="p">;</span> <span class="c">/* Changed from 60px */</span>
193        <span class="n">box</span><span class="o">-</span><span class="n">sizing</span><span class="o">:</span> <span class="k">border</span><span class="o">-</span><span class="n">box</span><span class="p">;</span>
194    <span class="p">}</span></code></pre></div>
195
196<p>By increasing the top and bottom padding by 10 pixels we have subtracted even more space available for the 100% of the childrens height,
197causing our <strong>content-modules</strong> element to have space between the top bar and the bottom bar. The children of the <strong>content-modules</strong> element can
198safely keep their height of 100% as they are relative to <strong>content-modules</strong>.</p>
199
200<p><img src="/assets/img/stretch5.jpg" alt="Alt text"></p>
201
202<p>You can continue this exact process on each module itself if you want to define a stretch area on each module.
203F.ex. if every module should have a top-bar itself and the rest should be stretched, you can do the following:</p>
204
205<div class="highlight"><pre><code class="language-css" data-lang="css"><span class="nc">.module</span> <span class="p">{</span>
206        <span class="k">position</span><span class="o">:</span> <span class="k">relative</span><span class="p">;</span>
207        <span class="k">padding-top</span><span class="o">:</span> <span class="m">30px</span><span class="p">;</span>
208        <span class="n">box</span><span class="o">-</span><span class="n">sizing</span><span class="o">:</span> <span class="k">border</span><span class="o">-</span><span class="n">box</span><span class="p">;</span>
209        <span class="k">display</span><span class="o">:</span> <span class="k">inline</span><span class="o">-</span><span class="k">block</span><span class="p">;</span>
210    <span class="p">}</span>
211
212    <span class="nc">.module</span> <span class="nc">.bar-title</span> <span class="p">{</span>
213        <span class="k">position</span><span class="o">:</span> <span class="k">absolute</span><span class="p">;</span>
214        <span class="k">top</span><span class="o">:</span> <span class="m">0</span><span class="p">;</span>
215        <span class="k">height</span><span class="o">:</span> <span class="m">30px</span><span class="p">;</span>
216        <span class="k">width</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span>
217    <span class="p">}</span>
218
219    <span class="nc">.module</span> <span class="nc">.module-content</span> <span class="p">{</span>
220        <span class="k">height</span><span class="o">:</span> <span class="m">100%</span><span class="p">;</span>
221    <span class="p">}</span></code></pre></div>
222
223<p>And the html would be:</p>
224
225<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;bar-top&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
226    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;content-modules&quot;</span><span class="nt">&gt;</span>
227        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;module&quot;</span><span class="nt">&gt;</span>
228            <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;bar-title&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
229            <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;module-content&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
230        <span class="nt">&lt;/div&gt;</span>
231        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;module&quot;</span><span class="nt">&gt;</span>
232            <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;bar-title&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
233            <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;module-content&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
234        <span class="nt">&lt;/div&gt;</span>
235        <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;module&quot;</span><span class="nt">&gt;</span>
236            <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;bar-title&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
237            <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;module-content&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
238        <span class="nt">&lt;/div&gt;</span>
239    <span class="nt">&lt;/div&gt;</span>
240    <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;bar-bottom&quot;</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div>
241
242<p><img src="/assets/img/stretch6.jpg" alt="Alt text"></p>
243
244<p>Here is a fiddle of it: <a href="HTTP://JSFIDDLE.NET/5XNMF/">
244HTTP://JSFIDDLE.NET/5XNMF/</a>. Resize the height of your browser window and you will see that it stretches.</p>
245
246</div>
247      <center><a href="https://twitter.com/share" class="twitter-share-button" data-text="Check out..." data-via="christianalfoni" data-size="large">Tweet</a>
248        <a href="http://christianalfoni.github.io/feed.xml"><img src="http://www.vienna-rss.org/wp-content/themes/optimize/images/ico-rss.png"/></a>
249      </center>
250
251<div id="disqus_thread"></div>
252<script type="text/javascript">
253    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
254    var disqus_shortname = 'christianalfoni'; // required: replace example with your forum shortname
255
256    /* * * DON'T EDIT BELOW THIS LINE * * */
257    (function() {
258        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
259        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
260        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
261    })();
262</script>
262
263<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
264<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
265<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
265
266
267    </div>
268    
269    <div class="clear"></div>
270
271    <div class="footer">
272        <div class="profile">
273            <div class="img"></div>
274            <div class="details">
275                <div class="name">Christian Alfoni</div>
276                <div>Living in<br> <b>Norway</b></div>
277                <div>
278                  <a href="https://twitter.com/christianalfoni" class="twitter-follow-button" data-show-count="false">Follow @christianalfoni</a>
279<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
279
280              </div>
281            </div>
282        </div>
283
284    </div>
285</div>
286
287</body>
288</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.