CSS logo for articles

How browser lay out elements

Simplifying layout oddities in CSS

published: 06.02.2018 / comments 4

CSS layouts have long been complained about its inconsistency. Beginning front-end developers may find the result of HTML and CSS illogical. In this tutorial, I’m explaining the rendering and laying out elements to understand to understand what goes on in a browser.

This is not a scientific article with a detailed explanation of browsers rendering the page but a simplified description of the process for beginning front-end coders.

Content is the key to element size

Content is what browser is looking for when rendering the layout. Everything is based on content. If an element has no content at all, it has no size (height). Empty elements collapse in a browser window. From this, we can end up with a conclusion that browser will give element only the space its content requires! So what about whitespace?

Whitespace around element content

Elements can have whitespace around them defined with to CSS properties; padding and margin. Padding is space that is considered to be inside the element around the content. Margin, then again is space around the content outside the element. The border is a visible line around the element drawn between the padding and margin. So how much space does an element need from the browser?

padding + border affect element size – margin affect element position

padding & border

To draw the element, browser needs space for the content plus the whitespace and border. All this is added to the original content size. Let’s have an example of an image that is 300 pixels wide and 200 pixels high.

Here is an example of two images (actually one image with two CSS settings). The image size is 300 by 200 pixels. Both images are inside a <figure> -element. The first has a CSS class .pic and the second has the same class plus a class .bbox. Here is the CSS for this example. Again, you can open the example in another browser tab to see all of the code.

figure {
 display: inline-block;

img {
 max-width: 100%;
 height: auto;

.pic {
 width: 300px;
 padding: 10px;
 border: 2px solid #333;
 margin: 20px;

.bbox {
 box-sizing: border-box;

And this is how they use the browser window real estate.

Element size comparison with CSS default and border-box setting

As you can see, the <img> -elements has different sizes even though they are commanded in CSS to be 300px wide! The default CSS box-model adds padding and border to the element so the rendered size is image size + padding + border width! In this example it is 300 + (2*10) + (2*2) = 324px.

The second picture has a CSS property box-sizing: border-box; This rule makes the <img> -element contain the padding and border making the element respect our command to be rendered to 300px wide. This will affect the size of the content. If the overall width is 300px then the content is 300 – ((2*10) + (2*2)) = 276px.


Ok, padding and border alter the size of an element. So what does margin do? Margin change the position of the content. One may often think that that’s the same but it’s not. This has relevance in laying out elements inside a browser window. This is because the browser will lay out the elements by their content. Let’s have an example.

We are creating a <header> -element on top of a page. The <header> has background-color and inside the header, there is a <h1> -heading. The header background-color should start from the very top of the window and there should be enough space about the heading. But what happens with the following code.

    <h1>Element size in browser</h1>

This will look like this in a browser.

CSS Magin moving the content

As you see. There is white space above the <header> when there should be none. In my example, the <body> -element has no margin nor padding and <header> has no margin either. So what gives? Where does this white space come from?

If you check this with browser tools, you would notice that the content of  <h1> heading starts at the very top of the content of <header>. Notice the word content! Content is the key. The white space is from the <h1> -heading which has margin-top .67em. To be precise, it has the styling from browsers internal stylesheet, a.k.a ‘User Agent Stylesheet’. User agent stylesheet gives <h1> element property -webkit-margin-before: 0.67em; This is the whitespace above the header.

As we can see. Margin of <h1> -element push <header> away from the top of the page. How to fix this. First of all, you could remove the top margin from <h1> element but then you would need to give the needed space using padding-top inside <header>. My solution would be the simplest one. Just give <header> a padding-top: 1px; property in CSS. Padding will command the browser to lay out elements inside <header> to start counting the space they need under the padding.

Let’s give <header> a 1-pixel padding-top in CSS and this is what we’ll see in a browser.

Margin empty space fixed with padding

FIXED! Now the <header> content will start at the very top of the <body> and the <h1> inside <header> will start inside <header>. Layout as we wished.

Open the example in another browser tab

CSS Box Model

It’s CSS Box Model I have been talking about. It is plain simple but I have noticed that at the beginning of their studies many newcomers in front-end coding has not really understood how it affects laying out elements. And when you combine this with, let’s say – floating elements, we have all the ingredients to a mess. Then people start whining how difficult and complex and messy the CSS layouts are. But it really is not.

You need to understand the basics. Start using Bootstrap or such, is not an answer – Learning is.

CSS Layouts; Absolute positioning, floating, Flex and CSS Grid

All these CSS layout methods are needed today. To become a web developer or designer, one must know all these techniques. Flexbox and CSS Grid are new and powerful, very cool layout methods but they do not replace each other but supplement each other. They are worth their own tutorials. Stay tuned.


Author of this site: Kari Selovuo

I'm a web developer/designer, instructor, and writer who has a mind of a developer and a heart of a designer. I like to share my knowledge and help others learn web development.

Twitter: @KariSelovuo

Leave a Reply

Your email address will not be published. Required fields are marked *