The Box Model
Boxes Within Boxes Within Boxes Within Boxes
For real layout, the we first need to understand how CSS sizes elements—and how we can add space between them. This is called the
-
Introduction to CSS Layout – MDN
As usual. -
Layout – web.dev
This gets intogridandflex; we’ll talk about those next unit. -
Learn CSS Layout
An old-but-still-good run-through.
…Use the effectiveness of the former “background” quite deliberately, and consider the blank white spaces on the paper as formal elements just as much as the areas of black type.
box-sizing: content-box; per the spec.
box-sizing: border-box; the defacto standard. Most CSS resets will do this for you! Like we said, very common.
By default, all browsers’ box-sizing: content-box;—which means that the padding (and border) exists inline-size/width or block-size/height—so padding (and border) is then an
But this is often unintuitive for designers and doesn’t fit with most web design patterns—so it is very, box-sizing: border-box;—which makes padding and border exist padding (and border) is easier to think of as an
Let’s take a look at this box, going
Content
The width or height—or inline-size and block-size. (More on those soon.)
Padding
Next comes padding, which extends the element’s area around the content. It’s easiest to think of this as an box-sizing the more-intuitive border-box, above):
Padding – MDN
There will be many of these.
A Sidebar About Shorthand
Know that padding—and many other properties, including border and margin—
Shorthand Properties – MDN
Be wary of the siren call of shorthand properties!
| 1 value: |
All Directions/Sides |
| 2 values: |
top/bottom left/right |
| 3 values: |
top left/right bottom |
| 4 values: |
top right bottom left |
section { padding: 1rem; }
section { padding: 1rem 2rem; }
section { padding: 1rem 2rem 4rem; }
section { padding: 1rem 2rem 4rem 2rem; }
These three- and four-value rules are often harder to read and quickly understand though, so we tend to avoid them. You can
section {
padding-top: 1rem;
padding-bottom: 4rem;
padding-right: 2rem;
padding-left: 2rem;
}
…and Logical Properties
You can also now define all your box model properties using top/bottom, left/right) orientations, you can map your rules to the block-start/block-end, inline-start/inline-end).
CSS Logical Properties
Adrian Roselli has a very thorough explanation.
In horizontal, left-to-right writing modes (as in English):
/* These horizontal physical directions: */
padding-left: 1rem;
padding-right: 1rem;
/* Map to these logical directions: */
padding-inline-start: 1rem;
padding-inline-end: 1rem;
/* And this combined property: */
padding-inline: 1rem;
/* Also this physical dimension: */
width: 20rem;
/* Becomes this logical one: */
inline-size: 20rem;
/* Same for the vertical directions: */
padding-top: 1rem;
padding-bottom: 1rem;
/* Mapping to these: */
padding-block-start: 1rem;
padding-block-end: 1rem;
/* And this shorthand for both: */
padding-block: 1rem;
/* This physical size: */
height: 20rem;
/* Becomes this logical one: */
block-size: 20rem;
This start / end terminology will come up later with flexbox and grid, so it is a good habit/mindset to get into!
This allows your design/styles to behave in a
Border
Back to our box model, moving outwards, with border. Border is… the border around an element. It has its own border-width, border-color, and also border-style:
Border – MDN
Our first non-text design element! You are allowed.
border-block-start property value order here doesn’t matter! Isn’t CSS The various border-style options:
And fun with border-radius:
Margin
The last part of our box is margin—the space padding and border, you can specify it all around or on individual sides:
Margin – MDN
The space between things.
Margin has a couple tricks up its sleeve. First, it can have padding and border only take up space.) Just add a minus before the value and watch it bring things closer together:
Also margins
section to be 10rem, but it is only 6rem! They have And Their Units
Okay, so now we have all these box properties—but how do we specify the dimensions? CSS has many inline-size, block-size, and also padding, border, margin, and even font-size. (Picas, anyone?) We’ll look at some common ones.
<length> – MDN
Absolute Units
Maybe the easiest ones to understand, these are fixed to physical (well, sort of) sizes. In general, we try and avoid these as they are necessarily
With the many vagaries of screen size and density, the physical/ruler lengths will only be correct when you print. And maybe not even then!
.pixels {
block-size: 360px;
inline-size: 720px;
}
.inches {
block-size: 5in;
inline-size: 10in;
}
.mm {
block-size: 84mm;
inline-size: 400mm;
}
.pt {
block-size: 12pt;
inline-size: 72pt;
}
Relative Units
Most of the time we want to use relative units, which depend on and respond to their context—particularly as we think ahead to
These are distinctly and intrinsically
/* Relative to nearest “sized” ancestor. */
.percentage {
block-size: 90%;
inline-size: 75%;
}
/* Relative to viewport height/width. */
.viewport {
block-size: 75vh;
inline-size: 80vw;
}
/* Relative to `:root`/`html` font-size. */
/* These define our typographic systems! */
.rem {
block-size: 12rem;
inline-size: 2.4rem;
}
/* These are relative to an element’s font-size. */
/* `1em` is “one line.” */
.em { block-size: 14em; }
/* The cap height. */
.cap { block-size: 1cap; }
/* Roughly one letter width. */
.ch { inline-size: 1ch; }
/* The x-height. */
.ex { block-size: 1ex; }
/* A line-height (baseline to baseline). */
.lh { block-size: 1lh; }
/* These all have `:root`-relative versions too: */
/* `rch` `rcap` `rex` `rlh` */
Combine Them With a calc()
Often you will want to use different units together! Mixing types or otherwise doing some maths. For this we have the calc() function.
.flexible-and-fixed {
inline-size: calc(50% - 2rem);
}
.computer-do-the-math {
inline-size: calc(100% / 12);
}
Limit/Constrain Them
.constrained-width {
min-inline-size: 12rem;
inline-size: 50%;
max-inline-size: 24rem;
}
.constrained-height {
min-block-size: 6rem;
block-size: 100%;
max-block-size: 12rem;
}
/* Handy to watch your line lengths! */
p {
max-inline-size: 65ch; /* 65ish letters. */
}
CSS is big and massive and overwhelming and sometimes indefensibly nonsensical—but remember that you can do a surprising amount with just these basic properties!
No matter how complex it gets, it really always comes back to these basics.
Position
With an idea of how elements take up space, now we’ll look at how they exist and move together in the position sets this relationship.
Position – MDN
Interesting web work often uses position.
Static
By default, every element is static—just meaning its normal, stacked position in the document.
You’ll rarely, if ever, actually set this yourself—it’s the default!
static is the default. Be sure to scroll these examples!
Relative
The first thing we might want to do is adjust an element static position, which we can do with relative positioning.
Once you have set position: relative; you can use the logical inset-block-start, inset-inline-end, inset-block-end, and inset-inline-start values (with any of the units, above) to move the element away from its default, normal position in the flow:
Absolute
absolute positioning is somewhat similar to relative—but instead of placing an element in relation to its own default position, it uses the position of its nearest
So absolute elements will go “up the tree” of parents and wrapper elements until they find one set to anything other than default/static—
Importantly, position: absolute; also
This is often used for exacting, specific design element placement. But it is inherently
relative parent.
Fixed
fixed positioning also removes the element from the document flow, but it places elements with relation to the
So position: fixed; brings the element
This is often used for things like navigation elements.
Sticky
The most recent addition to the position: sticky; elements are placed according to the normal flow of the document, like static, until their nearest
This is often used for headers on tables and lists.
“Depth”
Okay, z-index is not strictly position properties have given us ways to make things overlap, and z-index is how we can decide the
Z-Index – MDN
This can be tricky to work with!
By default, items that are lower in the HTML (coming
position properties both create new stacking contexts, z-index: 1; moves even elements in front.
A whole lot of things make a new position changes) which is kind of like a
No amount of internal z-index adjustments can “break” something out of that group—which is one of the reasons why z-index of the group, as we do here!
Display
In our HTML introduction we briefly talked about block and inline elements—as set by the user-agent styles. These are the first two examples of the display property.
Display – MDN
Our block and inline elements (and later, grid and flex).
Block
As we discussed, most HTML elements are display: block; manually on an inline element, too. This would mean that it starts on a new line, takes up the full width available, and you can specify a block-size, inline-size, and use margin above and below:
block.
Inline
And then going the other way, you can make block elements switch to inline with display: inline;. They will no longer start on their own lines, will only take up as much space as their content/children, and block-size or inline-size (or any -block-start/-block-end) properties:
white-space property pre-vents the spaces in the paragraphs from collapsing!
But Also inline-block
You can also combine the qualities of block and inline with display: inline-block;. These elements take block-size and inline-size (and vertical margin) like
And Sometimes none
Setting display: none; hides an element visually (and from screen readers) in the document—as well as taking it out of the
This is a common way to hide/show (by setting another display property) elements on the page, but it will
…vs. Visibility?
You can also hide something visually
Visibility – MDN
This also hides elements from assistive technologies (screen readers).
Setting visibility: hidden; keeps the space an element had before, but makes it invisible and unable to be interacted with. The value visible is the default:
…vs. Opacity?
Another way to hide an element visually is to adjust opacity, which uses values on a scale from 0–1 or 0%–100%. This differs from visibility because elements with no (or partial) opacity can still be interacted with:
Opacity – MDN
The entire element
Keep in mind that display: none;, visibility: hidden;, and opacity: 0; only hide things in the
What About Floats?
Oh right, floats. Sometimes you’ll want to have an image or block flow within a block of text. There are a lot of ways to do this now, but the oldest (and sometimes still the trickiest) is a float.
Floats – MDN
You don’t see these used as much, anymore!
Left and Right
The declarations float: inline-start; and float: inline-end; take an element out of the normal flow and place it on the left or right side of its parent container.
Any text
Don’t Forget to clear
Since this takes the floated element out of the <p>) to not move up it needs to be clear: inline-start; , clear: inline-end;, or clear: both;.
Applied on the following element, it will make it stay entirely below (clear of) the
float problem on the second one.
If you have a parent wrapper and no following element, there won’t be anything there to
You can solve this broken look with a last-child to clear the container.
:after is a pseudo-element—which acts here as a last child that clears the div.
Generally, folks try and avoid floats—they aren’t common in modern design patterns and have been giving people headaches for… decades now.
They require you to know how long your content is and also how big your viewport/page will be—
What about flex and grid?
We’ll cover these next unit! They’ll make your (layout) life easier.
E.g.: ____________ H1 has a 1 character margin So does H2 P starts here and could go on forever. Wow, a 5 character left margin sure looks great! _____ | + + | Wow, you can do | @ | images as well? | --- | Then you'll |_____| want a 1 character margin on the left side. Until, you're below the image that is. This is where we [find] the simple stacked box model is a bit too simple.