Skip to content

Cascading Style Sheets (CSS)

If HTML provides the semantic content of a site, CSS works to provide emphasis on visual hierarchy and aesthetic elements. While not necessarily informational content, using CSS well should enhance your ability to make a visual argument in the form of a web site. In addition, CSS can make or break the accessibility of a site.

  1. Apply HTML, CSS, Markdown, and basic Javascript to develop well-structured, responsive World Wide Web Consortium (W3C) standards-compliant web sites.
  2. Evaluate and implement web accessibility measures consistent with the Web Content Accessibility Guidelines (WCAG) version 2 specification.
  3. Design front-end user experiences using accepted web design patterns, methods, and information structures.
  4. Identify and use strategies of successful visual rhetoric for the web.
  5. Compare and select web technologies such as static site generators or frameworks as appropriate candidates for building web sites. Course Resources
The Coding Workbook, “Getting Started with CSS”

Cascading Style Sheets (CSS)

Section titled “”
  • First proposed in 1994 by Håkon Wium Lie while working with Tim Berners-Lee
  • Codified in CSS 1 in 1996, with significant contribution from Bert Bos
  • Authored in such a way that the same markup can be used to present dramatically different page styles, for example:

You may not believe it, but the underlying HTML for these pages is the same. The only difference: The CSS.

HTMLCSS
Uses tags and elementsFeatures properties targeting tags using rules
Provides information structureProvides visual structure
Says nothing about element statesAdds ability to target element states (i.e. hover, visited)
Controls information architectureEmphasizes visual hierarchy
Semantic tags contribute to accessibilityClickable, well-spaced elements and color creates accessibility

Take for example the following HTML structure:

See the Pen Hello, World! by Douglas Luman (@dluman) on CodePen.

/* Target the body tag/element */
body {
/* Change page typeface */
font-family: system-ui;
/* Make the brackground orange */
background: #f06d06;
/* Make type white */
color: white;
/* Align all text in the middle */
text-align: center;
}

This brief snippet controls all <body> content. Adding or changing properties in this block would affect anything contained therein. This constitues a rule, encapsulated by { }. Each property rule terminates with a ;.

Examples:

  • A property: font-family
  • A value: system-ui

CSS can contain comments, pre- and post-fixed by /* */

The above example only features a few properties. You could see the whole list, but know that, like HTML, their context and relevant combinations varies widely by the individual property; not all of them use the same syntax, though there are several patterns to pick up.

Some of the main syntax patterns:

  • font-size: 12pt;
  • margin: 0 auto;
  • border: 1px solid #D9D9D9;
  • display: block;
  • color: #FFFFFF
  • margin: 0 1rem 2rem 3rem;
  • --printers-black: #222;
  • ...

You will memorize the ones you use the most, and look up those that you don’t. While there may be some developers who can recite the majority from memory, it’s highly unlikely that anyone does; mostly, completion and other automatic tools fill in.

MDN Box model showing an element surrounded by padding and margin

The Box Model (MDN)

The above diagram demonstrates a core principle of CSS and the Document Object Model (DOM). Simply put:

Everything in CSS is represented as a box.

The model used contains a few elements in the following order:

  • the content
  • padding
  • border
  • margin

The standard model allocates the majority of size to the content. This is the default assumption. Developers can specify this by using the box-sizing: content-box property, but (as written) this setting is the default implied by the browser.

For example:

See the Pen Untitled by Douglas Luman (@dluman) on CodePen.

The following diagram represents the box model representation of the element at left from the outside-in:

  • margin of 48px (3rem)
  • border of 16px (1rem)
  • padding of 48px (3rem)
Box model representing diagram at left
padding
represents additional spacing inside an element
border
represents the border around an element
margin
indicates the area around the border, between elements

The alternate model includes the padding, margin, and border in its sizing calculation, giving the remainder to the content. This is triggered by giving an element the box-sizing: border-box; property.

See the Pen Untitled by Douglas Luman (@dluman) on CodePen.

Notice how the content here appears smaller due to the deprioritization of content space allocation. This approach is used more often in modern web design, as it prioritizes the elements rather than the content. Doing so permits layouts to line up more easily.

CSS features a number of different sizing units. Some may be more familiar to you than others:

UnitMeaning
pxPixel
ptPoint
%% of parent element
remReference to root element size (typically 16px)
emReference to element font size
vhViewport height
vwViewport width

Using the simplest approach:

block
elements take up full available width and always start a new line
inline
elements only take up the space necessitated by the content and do not create new lines
inline-block
elements allow setting width, height, et al., like a block element, but flow with the content line

Consider:

See the Pen Block, inline, and inline-block by Douglas Luman (@dluman) on CodePen.

CSS binds itself to HTML by changing:

  • elements
  • classes
  • ids
TypeRole
elementsprovide HTML structure and semantic meaning
classescreate reusable categories sharing styles
idsrepresent unique items (one per page) styled distinctly

The following minimal example demonstrates:

See the Pen Classes and IDs by Douglas Luman (@dluman) on CodePen.

TypeRole
classes
  • repeatable
  • prefixed in stylesheets with .
ids
  • unique
  • prefixed in stylesheets with #

In our above example, however, notice that the implementation of these properties do not need . or # in HTML: they are attached to elemnents via the class and id attributes.

Designers enjoy a greater range of ability when laying out pages that the original HTML/CSS specifications provided. Typically, the modern web is laid out using some combination of grid elements and flexbox layouts.

For this session, we will focus on grid layouts.

See the Pen Grid by Douglas Luman (@dluman) on CodePen.

Using the display: grid; property allows designers to create aligned designs in two dimensions (x and y). Much like a table in Excel or Google Sheets, there are creative ways to merge cells to allow content to take up more than one column or more that one row. Here, we introduce a new unit as well, the fr:

.grid__2_col {
/* Display this block element as a grid */
display: grid;
/* Make it 50 x 1 unit of viewport width */
width: 50vw;
/* Make each column 1 fractional unit (fr), and repeat twice (2) */
grid-template-columns: repeat(2, 1fr);
}

The div is the first real unsemantic element that we’ve encountered: it’s a general use, multipurpose player. Generally speaking, the div is meant to provide two purposes:

  • create groups of semantically- or arbitrarily-related content
  • develop areas of pages to style

As we will see in future weeks (and you might have already seen in other pages), the div is an accessibility issue, but is one of the (if not the) most used elements on the web. We’ll square this when we talk about ways to make them more accessible through metadata.

Anything can be “grouped” in a div, and we can apply class and/or id properties to them. It becomes necessary to use them, but if we do so in an intentional way, we can make our layouts rely on these generic items less.

Since 2022, the CSS specification supports CSS variables. These expressions are powerful tools in making sure that properties which need to be repeated use the same values all the time.

In practice, this uses the :root psuedo-element:

:root {
--webco-color-purple-bg: #432194;
--webco-color-gray: #D9D9D9;
--webco-printer-black: #222;
--webco-white: #fff;
}

Using these variables often looks like this:

header {
background: var(--webco-color-gray); /* Notice the var({VARIABLE}) syntax*/
height: 3rem;
align-items: center;
display: grid;
grid-template-columns: repeat(3, 1fr);
padding: 0 3rem;
}

This can be used for more than just colors, though. Take, for instance, standardizing a type face:

:root
{
--webco-primary-type: "Inter", sans-serif;
}

Putting this into practice:

html {
font-family: var(--webco-primary-type);
}

Using variables for common values goes far toward maintaining unity and the overall polish of your site’s aesthetic.