The display and visibility properties
can be very useful for responsive
design
and to add a bit of functionality to a web site. You can use both to
show and hide elements, and you can use the display
property to change how elements and/or their contents behave in
different layout scenarios.
Pre-Requisites
Before doing this tutorial, it is recommended that
you first read about responsive
design.
It's also helpful if you understand the basics of
media queries.
The Display Property
The display property is used to change the
layout behaviour of an item, and also to show/hide
an element. It can also be used to define how the layout of the element's
children will behave. We'll talk about showing and hiding elements in the last
section of this lesson. For layout, the display
property can define whether or not an element behaves as a block
element or an inline element, or whether or not it's a
FlexBox container or
Grid container.
The possible values for the display property are:
Defining the layout behaviour of the element itself:
block: makes the element behave as a block element.
inline: makes the element behave as an inline element.
inline-block: makes the element behave like an inline
element but maintains some characteristics of block elements.
Defining the layout of the element's children:
table: the element behaves like
an HTML table, but you have to use
it with children that are assigned display properties that
are part of the same table display model. Here
is a CodePen example that uses the display:table model compared to
a regular HTML table. Note that you should only use the display:table
model if you have a specific need to, otherwise you should use
a regular HTML table for displaying tabular data.
One very common use of the display property is to
change an element's behaviour as a block or inline element. For example,
in a responsive page or app,
you might want links in a navigation bar to appear stacked vertically
when the screen is small, and to appear in a horizontal row when
the screen is wider. This can be done by changing the display
property in a media query:
In this example, the links are styled as block elements by default,
and when the screen reaches a size of 758px in width or higher, they
change to inline elements.
The inline-block Value
To review the characteristics of block and inline elements:
You can set width and height of block elements, but width and
height on inline elements are ignored.
You can set borders, margin, and padding on all sides of block or
inline elements.
On block elements, borders, margin, and padding affect both the
size and positioning of surrounding elements (i.e.
a margin will move adjacent elements farther away).
On inline elements, top/bottom borders and padding change the size
of the element but not the positioning of surrounding elements, which
could cause the element to overlap surrounding elements. Top/bottom
margin is ignored on inline elements.
Also, on inline elements, left/right borders, margins, and padding
do not change the size of the element but do affect the positioning
of surrounding elements (e.g. a margin will move adjacent inline
elements farther away)
So what the heck is the inline-block value for?
Sometimes you want to display block elements as inline elements, but you
still need to treat them as block elements. For example, inline elements
CSS height, width, and top/bottom margin, but left/right padding/margin
doesn't affect the size of the element. Using inline-block defines
an element to display inline, but it will respect the height, width, and
top or bottom margin/padding that was defined in the CSS.
Examine the following CodePen below: There are three <div> elements
inside a <section> and all three divs are set with display:
block;. This does nothing spectacular: DIV elements are already
block elements, so using display: block on them is redundant.
However, change the declaration to display: inline;
and watch what happens.
Notice that even though I defined each <div> with a height and width
of 200px, none of the divs are 200px in width or height anymore:
for inline elements, the width is always the width the element needs to fit
its contents, and the height is the standard line height plus any padding
that has been added. That's why, on a narrower screen,
you see the <div> elements overlapping each other vertically:
Because the top/bottom padding changes the height of the DIVs but not the layout
of the surrounding inline elements, the DIVs overlap each other.
You can see that the left/right padding is being respected: there is a
clear amount of spacing between the contents of the DIVs and the
inner border of the elements.
Notice also that the top and bottom margin are now being ignored: when
the screen is narrow, the top/bottom margin does not add any
space between the elements vertically. However,
you can still see that the left/right margin is being respected:
you can still see the left/right gaps between the elements.
Now change the declaration to display: inline-block;.
You'll notice that the height and width of the <div> elements returns,
all the margin and padding is being respected, but the elements are displayed
side-by-side as inline elements would be displayed.
The inline-block element is useful when you want
to display block elements inline but you need height/width and
all margins/padding to be respected (not ignored).
Here's a similar example with nested DIV elements:
Notice that when you change display: block to
display: inline for for the nested div element, it
flows with the rest of the text content inside the outer <div>.
It also loses it's top/bottom margin. Also, if you make the screen narrow
enough, you'll see the nested DIV overlaps the content of the
outer div because the nested DIV has padding that doesn't affect
the outer div.
Now change inline to inline-block and
you can see how the top/bottom margins and padding comes back, and
there's no longer any overlap on a narrow screen.
The display property has a few other values for
more advanced formatting that you can check out in the
MDN: display
property documentation.
Showing/Hiding Elements
Showing and hiding elements is a useful thing to be able to
do: If you've seen web pages with a bunch of clickable tabs
that show different pages of content, you've seen this working!
Showing and hiding elements can be done with the display: none
declaration and also with the visibility property.
The visibility Property
The visibility property changes the visibility of an element
(duh). It can take one of 3 values:
visible: the item is visible
hidden: the item is hidden, it is not visible
the element is still used by the layout, it is still taking up space
it would normally use if visible
note that any childen in the element with
display: visible will still appear
collapse: this value only works on table rows/columns,
table row/column groups, or flex items: these items are hidden and
they don't take up space in the layout
In the CodePen below there are three <div> elements, but on the
second/middle div, I've set visibility: hidden;. You can
see that the div does not appear, but you can see the big gap between
the first and third <div> elements: that's where the second/middle
<div> is sitting. Even though it's not visible, it is still taking
up space: it is still part of the document flow.
Go into the CSS tab and comment out display: hidden;
and uncomment the line with display: none;
After making this change, you'll see that the space with the middle
div collapses, leaving the first and third div elements side-by-side.
So if you want to hide an element completely, you can use
display: none, and if you want to hide an element but not
allow other elements to take up the space, you can use
visibility: hidden.