CSS Display Properties: The Pillars Of LayoutWritten by Larry Botha |
Before mastering any craft, you need to get to grips with the building blocks of that craft. With a strong foundation, you feel confident in experimenting, trying new techniques, and creating something that you’re proud of. Without the basics, you’ll fumble about, frustrated, wasting time, and helping no one.
Writing good CSS is no different – and it all starts with understanding what you’re working with, before you write a single line of CSS.
Where does a page’s default layout come from?
Apart from the document flow (things in the beginning of your HTML appear before those later in the document), why is it that certain elements behave the way they do, while others behave another way? Why does a paragraph occupy the full width of content, and have margin, while an anchor only occupies the width of its text, and doesn’t play nicely with margin? What controls this before I add CSS to a page?
Browsers that render to a screen will define their own CSS to govern the default layout of HTML elements. These stylesheets are called the user agent stylesheets, and are responsible for a mostly consistent experience across the different browsers.
For every element that the WHATWG (the folks who decide which elements we need and don’t need in HTML, among other important matters) define, each browser will define CSS affecting how it renders on your screen. This CSS is not much different to the CSS you will write, and can override.
For example, this is the declaration for the body tag as defined by Webkit’s UA stylesheet:
What’s that – the body tag is actually using
Yup, and you can change that to whatever you want. In fact, let’s inspect the
head tag and its children:
All of those elements are there on the page, hidden away from sight, free for you to tinker with in your own stylesheets.
Understanding display properties
So what does this mean for us?
We now know that all elements, including the ones we can’t see, are assigned CSS properties to determine how they appear on a page. Understanding what a few of these properties do is going to be a major advantage in writing good CSS, and will in some cases allow us to not even have to write CSS since it’s already been written for us! We get to use what the browser gives us, free of charge.
Below I’ll cover a few of the most common and useful display properties, how you can think about them, and how they differ from each other.
Based on experience, we know that the
p tag behave in a similar way. Let’s take a look at what’s going on in Webkit’s UA stylesheet:
We can see that both
p tags are assigned
display: block;. In fact, the two elements differ only in that one has margin applied, and the other has none. This is a subtle but important distinction we will soon leverage.
Assigning elements with
display: block; makes them block-level elements, which have the following useful characteristics:
- They occupy the full width of a container by default
- They respect top / bottom padding and margin values
These two characteristics are incredibly useful.
Got two links, but you want the second on a new line? Wrap the first in a div!
Want some space above the second link? Wrap the first in a paragraph!
The example below illustrates how
div tags differ.
See the Pen Fixate Blog – The Pillars Of CSS Layout – display: block; Example by Larry Botha (@larrybotha) on CodePen.
You don’t need to write any CSS to achieve those layout modifications – you’re letting the user agent stylesheet do the work for you. You can go further and fine-tune what you want, but you don’t need any special classes to handle full widths or new lines (you can use a
br tag, too, depending on your layout requirements, but the principle remains. Just don’t stack
br tags next to each other, you should probably use CSS instead).
Inline-level and Inline-block-level Elements
Another common display property is
You’ll find this property on anchors, spans, strongs, and a slew of other mostly typographical elements. Inline-level elements allow us to stack HTML elements next to each other, without affecting the vertical layout of our pages.
Although useful, this can initially be frustrating and confusing when properties you are used to using cease to work. The feature that makes inline-level elements frustrating to work with is quite simple.
Inline-level elements ignore most vertical and horizontal layout properties.
Height, top and bottom padding, and top and bottom margin properties will all be ignored, as well as widths. Links, buttons, spans, and other naturally inline-level elements can all be a source of frustration before understanding what’s going on.
But there’s an amazing property to the rescue – one of my favourite CSS properties, in fact.
This property gives you the best of inline and block-level elements in one.
See the Pen Fixate Blog – The Pillars Of CSS Layout – display: inline-block; Example by Larry Botha (@larrybotha) on CodePen.
Of particular interest in the example above is when the elements are
display: inline; and when vertical padding and visible layout are toggled on.
You can clearly see the padding occupying space around each piece of text – but the layout remains unaffected.
From the demo we now know inline-block-level elements have the following characteristics:
- Similar to inline-level elements:
- They occupy only the width of their content – as if they are shrink-wrapping around their content.
- Similar to block-level elements:
- They can be assigned explicit widths
- They respect vertical margins and padding
There is one nuance to how inline-level elements differ to inline-block-level elements when it comes to wrapping to new lines:
An inline-block-level element will stack with other non-full width elements, until its content width reaches the full width of the container, at which point it will always occupy its own line. Inline-level elements, in contrast, will always wrap to new lines with adjacent non-full width elements.
Display Properties And Vertical Alignment
Another incredibly helpful attribute of inline-block-level elements is that they also respect the
vertical-align property for differing vertical heights.
Let’s explore this in contrast to inline-level and block-level elements:
See the Pen Fixate Blog – The Pillars Of CSS Layout – vertical-alignment Example by Larry Botha (@larrybotha) on CodePen.
From the example we can see that inline-block-level elements respect vertical alignment for both padding and line-height properties.
Block-level elements don’t respect any vertical-alignment values, while inline-level elements respect vertical alignment when adjacent elements differ by line-height.
Knowing When To Use What
Understanding how these basic properties work will win you half of your layout battles.
display: inline-block; and
display: block; are but two of a myriad of available display properties, but they will get you to where you need most of the time.
The easiest way to begin approaching layout is by asking yourself a few questions:
Do I need my content to be shrink-wrapped, and respect vertical layout properties? Do I need adjacent elements to align vertically? Then
display: inline-block; is usually your first go-to property.
Do I need my content to naturally occupy 100% of the width of its container, or occupy its own line? Then
display: block; (or even just a
div) will usually do.
If your layout needs are not met at this point, you’ll usually find what you want with the awesome
display: table; and
display: flex; properties – both of which deserve their own articles.
Understanding what browsers are doing before you write your own CSS is important in writing scalable and maintainable CSS. If you know what the browser is doing, you can reduce the amount of CSS you need to write, increase the speed at which you write, and will enjoy writing and maintaining your styles, too.
Become familiar with the default elements, their display properties, and how applying other display properties affects them.
They form the foundation of every site you build.