ashen.earth

code ramblings and technical oddities
12/4/2019

A Beginner's Guide to HTML: Layout and Display

Some early thoughts for a friend

Welcome back! It's been a while, but today we're going to talk about web stuff - I've been meaning to write a beginner's guide for a friend, so today's the day!

We're not going to get too far into depth, we'll just be going over the basics of browser layout, and how to use display inline, block, and inline-block elements.

Note: This post will not be addressing flex or grid elements - I plan to cover those in a later post.

Browser Layout and the Display Property

Every element in an HTML page has a display property - you might see it defined in CSS like this:

img.photo {
display: block;
}

img.icon {
display: inline;
}

img.galleryCard {
display: inline-block;
}
img.photo {
display: block;
}

img.icon {
display: inline;
}

img.galleryCard {
display: inline-block;
}

This instructs the browser to render various elements as either display: block, display: inline, or display: inline-block. But what exactly do these display rules mean?

Generally speaking: block elements are elements which the browser renders as a box, and inline elements are elements which the browser renders as flowing text. Let’s get into that a bit more!

Block elements:

  • Can have a defined width and height
  • Can be given both vertical and horizontal margins
  • Clear the whole width of their container

Block elements are typically things like <div>, <ul>, and header (<h1>…<h6>) elements - although most HTML elements can be rendered as a block if you enforce it with the display: block rule. Here’s a quick example:

<div style="
padding: 10px;
background: gray;
color: white
">
<p>This box is display block. Notice it takes the full width of its container.</p>
</div>
<div style="
padding: 10px;
background: gray;
color: white
">
<p>This box is display block. Notice it takes the full width of its container.</p>
</div>

This box is display block. Notice it takes the full width of its container.

See how this box automatically takes the full width? We can give it a fixed width and it will behave slightly differently:

<div style="
width:200px;
padding: 10px;
background: gray;
color: white
">
<p>This box is display block.</p>
<p>It is constrained to be 200px wide.</p>
</div>
<div style="
width:200px;
padding: 10px;
background: gray;
color: white
">
<p>This box is display block.</p>
<p>It is constrained to be 200px wide.</p>
</div>

This box is display block.

It is constrained to be 200px wide.

Let’s look at what’s going on here:

  • The box is set to have a width of 200px
  • We give it 10px of padding on each side (so the text doesn't run right up to the edge)
  • We set the background color of the box and text color for elements in the box

Remember how initially I mentioned that block elements clear the width of their container? Let's demonstrate that:

Text before the block element . . .

Even when we remove the centering margin - block elements clear the whole width of their container.

Text after the block element . . .

Block elements clear all of the space to the side of them by default. This can be convenient sometimes, but other times it will be a bit annoying - try putting a border around a <h1> tag sometime, unless you’re clever the border will extend to the full width of the page.

So if that’s block elements, how are inline elements different?

Inline elements:

  • Flow from line to line, filling the space defined by their closest block ancestor
  • Cannot have vertical margins
  • Do not clear space to either side of them

Inline elements are things like <a>, <b>, <i>, and <span> tags. These are effectively treated as text, they wrap at the end of the line, and generally flow like you would expect text to in a word processor, although they don’t necessarily have to be text:

<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>

Notice how when your screen isn't wide enough for all of them, these kitten images wrap at the end of the line? Also of interest is that there is a space between each of them (from the whitespace in our source code) but not between different rows of images. Images are by default display: inline so the browser tries to use its text-layout rules for how it should display these kittens.

One downside to inline display elements like this is that we have very little control over how much space is around our kittens - we can set a left or right margin, but there’s no way to make sure we have vertical spacing between the rows. We’ll see in a bit how we can use inline-block to get around this, but let’s keep exploring how inline works for a second.

Because these images are treated as very tall text, other text immediately before or after the kittens can also get weird - inline elements don’t clear space beside them like block elements:

Text immediately before an image
<img src="https://placekitten.com/100/100"/>
<img src="https://placekitten.com/100/100"/>
Text immediately after
Text immediately before an image
<img src="https://placekitten.com/100/100"/>
<img src="https://placekitten.com/100/100"/>
Text immediately after
Text immediately before an image Text immediately after

But remember we said before that any of these display properties can be overwritten?! If we instead set our kittens to be display: block then we see that our kittens suddenly behave much more like our space-clearing box from earlier:

Text immediately before an image
<img style="display: block" src="https://placekitten.com/250/300"/>
Text immediately after
Text immediately before an image
<img style="display: block" src="https://placekitten.com/250/300"/>
Text immediately after
Text immediately before an image Text immediately after

Note: This technique of setting images to be display: block is often used for illustrations on the web - just add an auto side margin and it’s even centered:

Illustration of a kitten:
<img style="display: block; margin: 20px auto" src="https://placekitten.com/200/300"/>
(Text after the kitten)
Illustration of a kitten:
<img style="display: block; margin: 20px auto" src="https://placekitten.com/200/300"/>
(Text after the kitten)
Illustration of a kitten: (Text after the kitten)

Now you might be thinking “Couldn’t I just use <p> tags for my text and not have to deal with this display: block stuff?” . . . well yes. Sort of.

It’s true that if you put your text in <p> tags then you get a nice result more or less for free:

<p>Text in a &lt;p&gt; before an image</p>
<img src="https://placekitten.com/300/200"/>
<p>Text in a &lt;p&gt; after</p>
<p>Text in a &lt;p&gt; before an image</p>
<img src="https://placekitten.com/300/200"/>
<p>Text in a &lt;p&gt; after</p>

Text in a <p> before an image

Text in a <p> after

But even here, you’re dealing with the pernicious influence of the display: block - <p> tags are block elements! This might seem counter-intuitive at first because we started by describing inline elements like flowing text, and <p> tags are literally for text, but I promise it makes sense: <p> tags represent a paragraph, and a paragraph should fill the width of its container. (Now, the text inside the <p> tag is inline, but that’s another story . . . )

So anyways, now that we’ve exposed the dirty secret of <p> tags, what exactly are inline-block elements?

Inline-Block: A Surprisingly Useful Hybrid

So it should come as no surprise to you that an element with the style rule display: inline-block should behave in some ways like an inline element, and in some ways like a block element. inline-block is useful because it allows us the control over width, height, padding, and margin that a block element does, but it can be used a situation where block doesn’t work - primarily where you want your elements to come one after the other within the same line like an inline element.

This kind of element is commonly used for photo galleries or navigation menus like this:

<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Home</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Posts</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Contact</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Home</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Posts</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Contact</a>
HomePostsContact

There are a lot of different ways to use inline-block elements, and for a long time it was the preferred way to make several block elements that flowed from left to right rather than just top to bottom. Nowadays this use has largely been replaced by the new CSS flexbox and grid rules - but we’ll have to talk about that another time!