Search

Pony Foo

Ramblings of a degenerate coder

CSS For Dummies

(1 comment)reading time: , published

Web design today is hard to get right. I've been meaning to talk about front-end design for a while, but I couldn't get the subject quite right. Seeing how detailing the underlying browser technology in JavaScript, I figured I'd do the same for CSS.

I'll be taking a different approach, though. Rather than explain what libraries do, I'll try explaining why a need for them was born, and walk you through the most basic stuff, such as selectors, and follow up by tackling complex topics such as fonts, Bootstrap, pre-processing, and more.

Fundamentals

CSS was born out of necessity. The necessity to separate content from presentation. The idea was to put behind stuff like <body bgcolor='black'>, and work towards a more layered approach. DOM elements would get CSS classes (more on that later), and in our CSS, we would define style rules, such as background-color, or font-size.

The previous example would be redefined as:

<head>
    <style>
    body {
      background-color: black;
    }
    </style>
</head>

<body>

The CSS is contained in a <style> block, or it can be alternatively be placed in an external stylesheet. Like so:

/* style.css */

body {
  background-color: black;
}
<head>
    <link rel='stylesheet' href='style.css'>
</head>

<body>

Alternatively, you can set styles in DOM attributes, or through JavaScript. The former is hardly ever recommended, with an exception being made in the case of HTML emails. The latter is sometimes useful when calculations are needed, but it's generally bad practice otherwise. JavaScript is useful for toggling (adding and removing) CSS classes on DOM elements, to denote a change in state.

<body style='background-color: black;'>
document.body.backgroundColor = 'black';

Note how the notation changes in JS. As a general rule, style properties are camel-cased in JavaScript, and hyphenated in CSS.

Classes

We mentioned classes earlier. Classes can be styled in CSS style sheets by prefixing them with a dot.

.my-class {
  background-color: black;
}

They can be added to DOM elements using the class attribute. Multiple classes can be added to each element.

<body class='my-class'>

<body class='my-class that-one another'>

The Cascading Aspect

Thus far, we've been discussing Style Sheets, but remember, these are also Cascading, hence CSS. So what does cascading imply?

Cascading means that order matters. That is to say, styles follow a convoluted order of precedence rule-set. This order of precedence can be overridden appending !important to the end of our style values, but this is a hack, and not recommended.

Instead, we should design our style sheets so that our rules cascade into each other. If we find ourselves resetting a bunch of properties from a less specific selector, in a more specific one, that should signal trouble (more on selectors in a minute).

Selectors

Selectors are what we use in CSS to identify the elements we want to style with a particular set of rules. If you are a JavaScript developer, you probably already used selectors with jQuery, or with the native methods that underline its selector engine.

A quick overview of selectors:

/* elements with the given id */
#element-id /* matches <anything id='element-id' /> */

/* elements with the given class name */
.class-name /* matches <anything class='class-name' /> */

/* span DOM elements */
span /* matches <span/> */

/* elements with an href attribute */
[href] /* matches <anything href /> */

/* data-foo property with value equal to 'bar' */
[data-foo=bar] /* matches <anything data-foo='bar' /> */

/* 'star selector', matches everything */
* /* matches <anything /> */

/* the currently focused element */
:focus /* matches <anything />, when active */

/* elements that are under your mouse pointer */
:hover /* matches <anything />, when you mouse over it */

/* selectors can be chained using spaces or special characters */

/* strong tag, one of its parents is an span */
span strong

/* strong tag, its immediate parent is an span */
span > strong

/* span tag immediately following a .title element */
.title + span

You can go deeper into selectors looking at the W3 recommendation, but these should be more than enough to get you going.

  • Keep your selectors as simple as possible. This will make them easy to read and interpret later on
  • You'll want to use classes to style your elements
  • Try and avoid nesting styles too deeply
  • Following an style guide might prove useful

CSS Properties

If you want to learn the different CSS properties you can apply, I'll recommend a few links.

Honestly, the best way to learn CSS from scratch, other than the fundamentals I describe in this blog post, is by googling. You want to style something in a particular way? Just google it. In all likelyhood, someone had that question before, and someone else answered it.

You can always learn more about CSS by subscribing to sites such as css-tricks.com.

Cascading Issues

Earlier on I mentioned cascading should be natural. Lets look at an unnatural example.

.button {
    border: 3px solid #ffc;
    border-radius: 5px;
    text-shadow: #999 0 1px;
    background-color: #fcc;
    padding: 8px;
    color: #f00;
}

.button.flat {
    border-radius: none;
    text-shadow: none;
}

Generally speaking, we'd be better off declaring this using a more natural approach.

.button {
    border: 3px solid #ffc;
    background-color: #fcc;
    padding: 8px;
    color: #f00;
}

.button.rounded {
    border-radius: 5px;
    text-shadow: #999 0 1px;
}

If the reason for this isn't immediately apparent, try thinking about this in a broader scope, where you have tons of overriding classes and many of them don't want the 3D appearance.

History of CSS

Now that we know the basics about what CSS is, and how to apply it to style the web, lets dive into a history lesson for a while. Or, at the very least, a few milestones in CSS history, so that we better understand the current state of the web.

In the beginning, different kinds of browsers started emerging. User agent stylesheets, shipped with each browser, presented different basic styles, and that represented a problem for web designers who wanted their site to look the same on every navigator. As a solution to this problem, the CSS reset concept was conceived.

CSS Reset

The main issue was with paddings, and margins. A first, naive fix for this problem, was to use the star selector, and simply reset padding and margin styles for every single element.

* {
    margin: 0;
    padding: 0;
}

This, however, raised performance concerns, and imposed unwanted resets on some elements, such as lists.

Thus, a better approach was born, and eventually prevailed. Eric Meyer created the CSS Reset, which is an improvement over the former. It resets more than just margins and paddings. It avoids using the star selector, but instead explicitly declares the tags it resets.

reset.png

In my mind, the main issue with reset.css, is the fact that it makes it really hard inspecting an element's styling, since really long reset statements are added on almost every single element, making it hard to read.

A more modern approach exists today.

Normalize.css

A modern, HTML5-ready alternative to CSS resets

Rather than reset everything, Normalize resets specific styles, in specific elements, and is thoroughly documented.

normalize.png

This has the added advantage of avoiding the long lists of CSS reset styles we see in our HTML inspectors when resorting to a CSS reset. As you can see, normalize offers a cleaner approach.

Browser inconsistencies

As you might know from JavaScript, browsers don't always implement things the same way, or at the same time. This is particularly nefarious when it comes to CSS 3 properties. As a result, some rules have to be written in several different ways if we want to maximize our browser support. For example, we might need to write border-radius, to give a rounded border to an element, like this:

-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;

We should avoid doing this kind of repetitive, and error-prone task by hand, and resort to a pre-processor such as SASS, or LESS, to help us keep our code DRY and concise. We'll go deeper into these topics in a later post.

CSS Grids

On another level, frameworks have been looming over CSS for a while now (more on frameworks in a future post!), with different end goals.

There are quite a few different grid systems such as 960.gs and semantic.gs, to name a few.

Grid systems basically consist of a bundle of classes that help you rapidly prototype a website's layout using the classes provided by the framework. These classes help you define how many columns each element takes up in a grid's row. Here's an example taken from the 960.gs site:

<div class="container_12">
  <div class="grid_7 prefix_1">
      <div class="grid_2 alpha">
          ...
      </div>
      <div class="grid_3">
          ...
      </div>
      <div class="grid_2 omega">
          ...
      </div>
  </div>
  <div class="grid_3 suffix_1">
      ...
  </div>
</div>

Before you jump on the grid system bandwagon, I'd advise you to check out Twitter Bootstrap. Bootstrap is a comprehensive rapid prototyping solution for the front-end.

I'll write more on bootstrap in a future post, but I wanted to introduce you to the magic world of CSS first.

The next article regarding CSS will include topics such as:

  • Intelligent ways to organize your CSS
  • CSS pre-processor options available (what, and why included)
  • A guide on what Bootstrap is, how to use it, and why it rocks

Later on, I intend to write about more advanced topics

  • Picking the right typeface for your site
  • Responsive web design and mobile first
  • Flat design!

If you're interested in these topics, make sure you subscribe via RSS feed or through email notifications!

Comments(1)

Eric Douglas

Lots of useful tips! Your site is simply amazing! I'm learning a lot here... Every morning I come here to have "a minute of wisdom".

A really appreciate your great job! Success!