Document Flow

HTML Documents without any styling information applied via CSS have a "normal flow" or default parameters for how the browser displays them. By default, html elements will all flow to the left, and be displayed one after the other in the order they exist in the HTML. Embedded links (anchor or 'a' tags) will continue as normal text in this flow, wrapping lines and flowing left.

The HTML (and any associated CSS) are rendered by the browser through a sequence of steps:

Certain styling applied by CSS can remove elements from the "normal flow" causing the resulting appearance of the web page to be significantly different from the layout of elements in the HTML. This can provide tremendous flexibility in what a page looks like without significant changes to the order or structure of the HTML. For both versatility and ease in development and support as well as accessibility for screen readers and other assistive technologies, HTML should be structured to provide semantic clues, readable code, and concise and clear editing structure. CSS should be applied via linked stylesheets (avoid inline styling to keep code clean) to handle the visual layout of the resulting page separately from the writing of the content in the HTML.

CSS Overview

CSS Stands for Cascading Style Sheets. Following the HTML being read by the browser and parsed into the DOM (Document Object Model), the browser will parse the CSS. CSS can be provided inline, at the head of a document, or as a separate linked style sheet. The latter of these three is the most flexible and generally best practice for readability and editability. Inline styling should generally be avoided as it causes clutter and is more difficult to edit and keep organized then keeping all your style rules in one place.

The Cascading portion of the acronym refers to how the style rules are prioritized/rendered. There can be multiple layers of rule selection that apply to a singular element in the HTML document. If any two rules are in conflict as the browser cascades through the sheet, the last rule listed in the style sheet will take precedence over earlier rules. If multiple selectors apply to a singular element and none of the rules are in conflict, then all will be applied. If the browser encounters any style rules that are incompatible or unreadable, it will simply ignore them and move on through the document.

CSS uses a number of possible selectors to figure out what rules should be applied to which nodes in the DOM. The selector is followed by {curly braces} Any applicable style rules between the curly braces will be applied to all nodes in the DOM matching that selector. Nodes can be selected by:

Selectors can be combined to increase specificity, or to apply the same rules across multiple selectors as follows:

Position Property

There are currently 7 possible settings for the position attribute of an element: static, fixed, absolute, relative, sticky, initial, and inherit.

Display Property

There are many possible settings for the display attribute of an element: The major types are inline, block, inline-block, flex, grid, table and none. Initial and Inherit also work on display.

Padding and Margins

Padding and Margins are similar CSS properties that affect the layout, primarily of block elements. Margin sizes affect the distance between containers and other elements on the page. Padding affect the distance between content and the border of its container. Margin will accept an :auto delcaration for centering purposes, but padding will not. Margins and padding can be differentiated for the four sides of the content in a single declaration in clockwise order - top, right, bottom, left. If only two values are declared, it will assume symmetry (left = right and top = bottom). Single sides may also be declared directly using padding-left or margin-left for instance.


Borders are drawn around the edge of a content area, outside the padding and inside the margins. Borders may have a variety of style, thickness, and color like many other HTML/CSS elements. Border properties include:

You must set a border style before you can set a width or color. Just like padding and margins, the 4 sides of a border can be set independently with different properties either through the use of multiple arguments or explicit selectors like border-top. Border width, style, and color can be set in a single declaration in that order (e.g. border: 5px solid red).

The property border-radius can be specified to round the corners of the border using the specified radial value.

Box Sizing

How the total size of an element is calculated depends on the box-sizing model in play. The default setting for this property is content-box which means the browser will apply any height or width specifications to the content only. Then padding, border, and margins will all be added to that content dimension externally. Alternately declaring box-sizing:border-boxwill include padding, border, and margins in the total size of an element which generally makes layout more consistent when aligning and sizing objects with a variety of padding, border, and margin configurations. The box-sizing:border-box; declaration is commonly made at the top of a stylesheet using the *, ::before, ::after selectors to apply the sizing model universally to all elements and pseudo elements.


CSS Flexbox is a display type that allows for flexible and responsive alignment and sizing of elements within the flex container. The container is set to a display type of flex and then the arrangement of elements may be adjusted with the following properties:


To utilize the CSS grid layout attribute, after setting the display property of the container via display:grid; you can adjust spacing (gaps) of the rows and columns of grid items. All direct children of the container set to display:grid become grid items. The grid consists of rows and columns of elements, with row gaps between horizontal groups of content and column gaps between vertical groups of content. These can be set uniformly with grid-gap. A singular value will set all the columns and rows to that width. You can specify different widths for column gaps and row gaps either by providing two arguments for grid-gap where the first argument sets row-gap height and the second sets column-gap width, or by explicitly calling out the separate properties grid-row-gap and grid-column-gap.

For example:
grid-gap: 20px 10px;

is the same net result as:

Grid dimensions can be set using grid-template-columns and grid-template-rows. The arguments for both of these properties specify the width of the column or row respectively (set all arguments to auto for uniform widths). The number of arguments provided will determine the number of columns or rows in the grid layout.

For example:
grid-template-columns:50px auto auto auto;
grid-template-rows:25px 50px;

defines a grid with 4 columns and 2 rows. The first column will have a fixed width of 50px, and columns 2-4 will have uniform width based on subdividing the remaining space in the container. The first row will have a fixed height of 25px and row 2 will have a fixed height of 50px.

Grid Items

When placing grid items, use the lines between the rows and columns to specify the area of the grid that item is to occupy.

For example:
grid-column-start: 1;
grid-column-end: 3;

will place an item that spans from the left edge of the grid to the line between column 3 and 4 of the grid. Similarly:

will place an item that spans from the gap between rows 1 & 2 of the grid to the gap between rows 4 & 5.

This can also be handled with a single declaration such as grid-column: 1/5; which would place an item between column gaps 1 and 5. You can also use the keyword span to specify a start and how many columns or rows an item will span. (e.g.grid-column: 1/span 3;)

It can be shortcut even firther using the grid-area command with the format grid-area: RowStart / ColumnStart / RowEnd / ColumnEnd or grid-area: RowStart / ColumnStart / Row Span / Column Span

grid-area and grid-template-area can also be used to name grid areas and map items onto them. When specifying grid-template-areas, each row in the grid is separated with matched apostrophes (') and each spaced argument within the apostrophes represents a column. You can us a period (.) to represent a grid space with no name.

For example:
grid-area: myArea;
grid-template-areas: 'myArea myArea myArea . .' 'myArea myArea myArea . .';

will specify a 5 column, 2 row grid (note the periods) where item1 will occupy the first 3 columns in both rows.