CSS - Practical Applications

Custom Properties

Let's start by establishing our desired theme colors. For more information about selecting colors check out Google's Material guidelines.

Once you've picked out your colors, let's use CSS Custom Properties to create a theme. By taking this approach, we can easily change our colors as they are all there in one place.

We'll start by selecting the 'root' element with the :root selector. This is essentially the same as using html as the selector, but is a bit more specific, so there is less chance of it being overridden inadvertently.

Next, we'll 'declare' a variable and assign a value like so:

html {
  --primary: #6200EE;
}

And to apply this variable to, for example, our <h1>:

h1 {
  color: var(--primary);
}

Go ahead and build out your entire color palette as shown above, and practice applying colors to a few different elements.

BTW, we are only using 'hexadecimal' format to define our colors. But, there are other approaches such as specifying RGB values or even using: hue, saturation and lightness, among others. If, you're interested in the other formats, check MDN's reference.

Here's an example implementation:

/* :root selector is basically same as 'html' in this context. */
html {
  --primary: #6200ee;
  --primary-variant: #3700b3;
  --secondary: #03dac6;
  --secondary-variant: #018786;
  --background: #fff;
  --error: #b00020;
  --primary-text: #fff;
  --secondary-text: #000;
  --border-primary: solid var(--primary-variant) 3px;
  --border-secondary: solid var(--secondary-variant) 3px;
}

body {
  font-family: "Poppins", sans-serif;
}

header,
section:nth-of-type(odd),
footer {
  background: var(--primary);
  color: var(--primary-text);
}

nav {
  border-top: var(--border-secondary);
  border-bottom: var(--border-secondary);
}

footer {
  border-top: var(--border-primary);
}

nav,
section:nth-of-type(even) {
  background: var(--secondary);
  color: var(--secondary-text);
}

CSS Units

There are many ways to express units in CSS. For our purposes, we will focus on px for most things it works well as a 'general purpose' unit.

However, for our font-sizes, we will use: ems. For better control over varying screen sizes and responsive behavior, we will also use vw (and vh). And, for our margins and paddings, we can use a related unit: rem.

Add the following rule to your body selector: font-size: 10px;. This sets up the base font-size for all of your other elements. So, now 1em and 1rem are both equal to: 10px. In this way, if I want font-size: 16px;, I can do: font-size: 1.6em. Likewise, if I want padding: 8px;, I can do: padding: 0.8rem;

In case you're wondering, there is a slight difference between em and rem. Summarily, using em allows a child to 'scale up' based on a px font on its parent, whereas, rem doesn't care what the parent's px font-size is; it always references the 'top-most' parent that has a px font-size; in our cse, body.

For our purposes, since we are only setting a px font-size on the html, em and rems behave similarly. However, generally speaking, using em for font-size allows us to enact 'special sizing/scaling' in specific parts of our website. But, usually margins and paddings are kept consistent based on html selector.

Now, why do you think we would want to use these types of relative units instead of just sticking with px all the way through?

Go ahead and update your font-sizes using ems for the rest of your elements so that they read nicely. Rather than being arbitrary about it, you could use a Type Scale.

Quick Recap Video

If you've followed along up until this point, then your results might look something like what's shown in this video.

A quick overview of HTML/CSS up until this point.

Flexing Our Layout

About Flexbox

  • display: flex sets up the parent element (much like position: relative did)

  • flex-direction tells the flex-box which way to 'flex': row for horizontally, column for vertically

  • flex-wrap tells the flex-box what to do with children when they've reached the edge of the parent. In this case, we're using wrap to wrap list elements around into a new row.

  • justify-content defines the spacing of child elements. They can be evenly spaced from the edges with space-around, maximize space between elements with space-between, or be clumped at the start, end, or center of the parent element with flex-start, flex-end, or center, respectively.

  • align-items defines how children should be aligned with one another on the axis perpendicular to the flex-direction. In this case, center vertically aligns all li elements. If flex-direction were column, center would align items horizontally.

  • And there you have it... a (mostly) responsive layout built with CSS! At this point, you can add any padding or margins you need to get your page looking pretty, then stage, commit, push, and deploy your changes.

Applying Flexbox

Now, let's concern ourselves with the layout of our page, starting with our mobile view (mobile-first web design).

One common approach, is to let our entire page take up 100vw, and then apply a display: flex and flex-direction: column to prevent a single column mobile layout.

The general idea is that, from here, we will use @media (Media Queries) to 'respond' to some minimum screen sizes, and update our layout accordingly.

We will start by applying flex to our <header>. We will turn <header> into a flexbox by applying display: flex; The result is that the direct children become flex children, and we can use some additional flexbox properties and values to position things nicely.

Introducing `flex` on `<header>`.

Now that we have our 'logo' and 'tag line' centered nicely on mobile, let's learn about border-radius. Try the following:

figure {
  border-radius: 20px;
}

Notice that all 4 corners of the <figure> are now rounded. Try the same thing, but try passing in 2 values, then 3 and then 4. Can you discern what the affect is?

Now, although we won't explicitly cover % units, as we tend to favor vw and vh, try the following: border-radius: 50%. As long as your <img> was a square to begin with, now it's a circle!

Another neat property is: box-shadow. With box-shadow, we can apply a shadow to things like the <figure>. Try the following rule on your <figure>: box-shadow: 10px 20px 20px black. Do you notice the dramatic shadow? (as always, do a 'hard refresh' to 'bust the cache' and see the changes. 'ctrl/cmd+Shift+R'). Usually, you can just play with the numbers to get the look you are after, but here are the details box-shadow.

Last updated

Was this helpful?