As Rachel Andrew has reminded us, everything in web design is a box, or the absence of a box. Not everything necessarily looks like a box—
transforms can be deceptive, but everything takes up a box-like space. Layout is inevitably, therefore, the arrangement of boxes.
Before one can embark on combining boxes to make composite layouts, it is important to be familiar with how boxes themselves are designed to behave as standard.
The box model
The box model is the formula upon which layout boxes are based, and comprises content, padding, border, and margin. CSS lets us alter these values to change the overall size and shape of elements’ display.
Web browsers helpfully apply default CSS styles to some elements, meaning they are laid out in a reasonably readable fashion: even where author CSS has not been applied.
In Chrome, the default user agent styles for paragraphs (
<p>) look like…
… and unordered list (
<ul>) styles look like…
In both the above examples, the element's
display property is set to
block. Block elements assume all of the available space in one dimension. Typically, this is the horizontal dimension, because the
writing-mode is set to
horizontal-tb (horizontal; with a top to bottom flow direction). In some cases, and for some languages (like Mongolian),
vertical-lr is the appropriate writing mode.
Inline elements (with the
inline) behave differently. They are laid out in line with the current context, writing mode, and direction. They are only as wide as their content, and are placed adjacently wherever there is space to do so. Block elements follow flow direction, and inline elements follow writing direction.
Thinking typographically, it could be said that block elements are like paragraphs, and inline elements are like words.
Block elements (also called block-level elements) afford you control over both the horizontal and vertical dimensions of the box. That is, you can apply width, height, margin, and padding to a block element and it will take effect. On the other hand, inline elements are sized intrinsically (prescribed
height values do not take effect) and only horizontal margin and padding values are permitted. Inline elements are designed to conform to the flow of horizontal placement among other inline elements.
A relatively new display property,
inline-block, is a hybrid of
inline. You can set vertical properties on
inline-block elements, although this is not always desirable—as the proceeding illustration demonstrates.
Of the basic
display types, only
none remains. This value removes the element from the layout entirely. It has no visual presence, and no impact on the layout of surrounding elements. It is as if the element itself has been removed from the HTML. Accordingly, browsers do not communicate the presence or content of
display: none elements to assistive technologies like screen reader software.
What are logical properties and does their existence imply the existence of illogical properties? English speakers accustomed to reading left to right (
direction: ltr) and top to bottom (
writing-mode: horizontal-tb) find it logical to use properties that include the words “left”, “right”, “top”, and “bottom” when applying styles like margin and padding.
It’s when the direction or writing mode changes that this becomes illogical, because left and right (and/or top and bottom) are flipped. Now the margin you put on the right you really need on the left.
Logical properties eschew terminology like “left” and “right” because we know they can be reversed, making the terms a nonsense. Instead, we apply styles like margin, padding, and border according to the block and inline direction.
margin-inline-end applies margin to the right. In a
margin-inline-end applies margin to the left. In both cases, it is applied where it is needed: at the end of the inline dimension.
When you apply
display: flex or
display: grid to a
<div>, it continues to behave like a block element, using
display: block. However, it changes the way its child elements behave. For example, with just
display: flex (and no other Flexbox-related properties) applied to the parent, its children will distribute themselves horizontally. Or, to put it another way, the flow direction is switched from vertical to horizontal.
Formatting contexts are the basis of many of the layouts documented in this project. They turn elements into layout components. In Composition, we'll explore how different formatting contexts can be nested, to create composite layouts.
Content in boxes
The web is a conduit for primarily textual information supplemented by media such as images and videos, often referred to collectively as content. Browsers incorporate line wrapping and scrolling algorithms to make sure content is transmitted to the user in its entirety, irrespective of their screen sizes and dimensions, and settings such as zoom level. The web is responsive largely by default.
Without intervention, it is the contents of an element that determines its size and shape. Content makes
inline elements grow horizontally, and
block elements grow vertically. Left to its own devices, the area of a box is determined by the area of the content it contains. Because web content is dynamic (subject to change), static representations of web layouts are extremely misleading. Working directly with CSS and its flexibility from the outset, as we are here, is highly recommended.
By default, the dimensions of a box are the dimensions of the box’s content plus its padding and border values (implicitly:
box-sizing: content-box). That is, if you set an element to be
10rem wide, then add padding on both sides of
1rem, it will be
1rem of left padding and
1rem of right padding. If you opt for
box-sizing: border-box, the content area is reduced to accommodate the padding and the total width equals the prescribed
Generally, it is considered preferable to use the
border-box model for all boxes. It makes calculating/anticipating box dimensions easier.
Any styles, like
box-sizing: border-box, that are applicable to all elements are best applied using the
* (“universal” or “wildcard”) selector. As covered in detail in Global and local styling, being able to affect the layout of multiple elements (in this case, all elements) simultaneously is how CSS brings efficiency to layout design.
Only where the height or width of a box is constrained does the difference between
border-box come into play. For illustration, consider a block element placed inside another block element. Using the
content-box model and a padding of
1rem, the child element will overflow by
inline-size: 100% (equivalent to
width: 100% in a
horizontal-tb writing mode) is applied.
inline-size: 100% means “make the width of this element the same as the parent element”. Since we are using the
content-box model, the content is made
100% wide, then the padding is added on to this value.
But if we use
inline-size: auto (we can just remove
inline-size: 100%, since
auto is the default value) the child box fits within the parent box perfectly. And that’s regardless of the
height is also set to
auto, meaning it is derived from the content. Again,
box-sizing has no effect.
The lesson here is the dimensions of our elements should be largely derived from their inner content and outer context. When we try to prescribe dimensions, things tend to go amiss. All we should be doing as visual designers is making suggestions as to how the layout should take shape. We might, for instance, apply a
min-height (as in the Cover layout) or proffer a
flex-basis (as in the Sidebar).
The CSS of suggestion is at the heart of algorithmic layout design. Instead of telling browsers what to do, we allow browsers to make their own calculations, and draw their own conclusions, to best suit the user, their screen, and device. Nobody should experience obscured content under any circumstances.