These free mini-courses will give you a strong foundation in web development. Track your progress and access advanced courses on HTML/CSS, Ruby and JavaScript for free inside our student portal.
Scroll down...
Welcome to CSS3! Just like HTML5, CSS has undergone a healthy revamping over the past several years. The old specification, CSS2, showed up in 1998 (and was updated to CSS2.1 in 2011). Just like with HTML5, CSS3 isn't a single massive release but the evolution of a standard over time. Because of this, the major browsers already support most features.
Where HTML5 helps you to add functionality to the page and better define the semantic structure of its content, CSS3 is all about expanding your available creative options. Some of its features, which we'll emphasize in this lesson, can make your life a lot easier than the hacks you'd otherwise have to implement. Others are best left until you've spent enough time with CSS to get truly familiar with its power (we'll briefly cover those at the end).
This lesson won't attempt to span the breadth of CSS3 (that'd take up the entire course). And, frankly, the best way to expand your CSS vocabulary is just to try and build something, Google for an example of it, and implement it yourself.
Our goals for this lesson are more targeted -- we want introduce some practical ways for using the dozen-or-so best new parts of CSS3. We'll be covering these in more detail as we move through the upcoming lessons.
Here's a quick look at what we'll cover below:
href
.%
and px
). Useful for those "Center it at 50% minus 40px" cases.:nth-child(4)
, and multiple backgrounds.Media queries are one of the biggest advances in enabling the convergence of web and mobile sites. Unless you've lived under a rock, you can see that mobile is a massive growth area and so serving mobile devices needs to be at the front of your mind.
Media queries basically allow you to ask the browser for some of its properties (like how wide the viewport is) and then only apply a group of styles if the specified conditions are true. This has allowed designers to create websites which "degrade gracefully" from a full-width layout to a single-column mobile-friendly grouping as the browser width is reduced.
Using media queries is extremely simple -- just specify a condition and anything inside the brackets gets executed if it evaluates to true. You can use it either within an existing stylesheet or on the link to import a stylesheet:
// CSS media queries on link elements
<link rel="stylesheet" media="(max-width: 800px)" href="example.css" />
<link rel="stylesheet" media="only screen and (-webkit-min-device-pixel-ratio: 2)" href="iphone4.css" type="text/css" />
// CSS media query within a stylesheet
<style>
.facet-sidebar {
display: block;
}
@media (max-width: 600px) {
.facet-sidebar {
display: none;
}
}
</style>
Check out the MDN Media Queries Guide for a comprehensive reference, but you won't need to dig too deep to use media queries effectively. The example above should tell you pretty much all you need to know about how they're structured.
For a live example, try resizing your browser and seeing what happens to the navbar on this site. At certain widths, media queries are activated and its properties are changed slightly.
Some of the properties you can use to define your query are:
// *** More Common ***
// Width
@media (min-width: 1100px) { ... }
// Height (of the browser viewport, not the HTML page)
@media (max-height: 400px) { ... }
// Screen aspect ratio (width / height)
@media screen and (min-aspect-ratio: 1/1) { ... }
// Orientation (common on mobile)
@media all and (orientation: portrait) { ... }
// *** Less Common ***
// Color (is it a color display?)
@media all and (color){ ... }
// Device properties (as opposed to page properties above)
@media screen and (device-aspect-ratio: 16/9) { ... }
@media screen and (max-device-width: 799px) { ... }
@media screen and (max-device-height: 799px) { ... }
// Grid (Is this a TTY accessibility device?)
@media handheld and (grid) and (max-width: 15em) { ... }
// Device resolution (e.g. the printer you're using)
@media print and (min-resolution: 300dpi) { ... }
For a more complete example, to specify a stylesheet for handheld devices and screen devices with a width greater than 20em, use:
@media handheld and (min-width: 20em),
screen and (min-width: 20em) { ... }
When working with media queries, there are a few tricks to keep in mind:
You can use the logical operators and
, not
, or
(by separating terms with commas) and only
to define your query. For instance:
@media screen and (max-width: 600px) { ... }
To specify an entirely different stylesheet, add a media
attribute to your link
tag:
<link rel="stylesheet" media="screen and (max-device-height: 799px)" />
Most of the properties just listed can be prefixed by min-
or max-
, which does exactly what you'd expect it to.
When you want to implement media queries, simply find an example on the web and copy it.
Media queries apply to more than just device properties. You can, for instance, specify a totally separate stylesheet for printing.
You've probably already found frustration dealing with the CSS box model, especially around how padding actually expands the height and width of the box. When things go all wonky on you, simply set box-sizing: border-box;
and feel the sanity slowly return.
"Border-box" fixes the width and height of the element. That means that the padding, instead of outwardly expanding the size of the element box like normal, will reduce the size of the inner content box instead. See the MDN docs for more info.
Just like being able to identify elements based on their tag, class or ID, CSS3 lets you target based on their attributes:
[attr=val]
-- matches a DOM element having the attribute attr and the value "val"[attr^=val]
-- matches a DOM element having the attribute attr and a value starting with val[attr$=val]
-- matches a DOM element having the attribute attr and a value ending with the suffix val[attr*=val]
-- matches a DOM element having the attribute attr and a value containing the substring valFor example, to emphasize all links that point toward the blog:
a[href*="blog"]{
font-weight: bold;
}
Or to target a specific input type (frequently used):
input[type=submit]{
font-size: 2em;
}
This used to be obnoxiously hard, and now... so easy with the border-radius
property:
button{
border-radius: 4px;
}
If you make the border radius larger than the height or width of the element, the element typically displays as a circle or like a round-ended hot dog.
You no longer need to use vendor prefixes (e.g. -webkit-border-radius
) with this property.
box-shadow
lets you specify a drop shadow for an element. It takes several inputs which determine the width and positioning of the shadow. Its inputs, in order, are:
box-shadow: horizontal-shadow vertical-shadow blur-width spread-width color [or inset or initial or inherit];
For example:
button{
box-shadow: 5px 15px 10px 0 #f00 inset;
}
See the box-shadow docs for details. You no longer need to use vendor prefixes (e.g. -moz-box-shadow
) with this property.
You can also add a text-shadow
, which does (predictably) the same thing to text. Use this sparingly unless you want your text to look awful...
You can use the calc()
function inside of CSS to do simple units-based arithmetic like subtracting 80 pixels from half the width of the containing div:
.banner {
width: 90%; /* fallback for browsers without support for calc() */
width: calc(50% - 80px);
border: solid black 1px;
box-shadow: 1px 2px;
background-color: yellow;
}
This used to be really frustrating stuff, so having the ability to do simple math directly in CSS3 has been a lifesaver. Play around with it -- it just sort of "works". See the MDN docs for more info.
It's not terribly new, but the ability to import external fonts to your sites was a big deal when the functionality first arrived. Now you can import fonts from Google, Typekit, or your own server just by using the @font-face
rule to specify its origin.
Web fonts are a two-step process -- they often first import a stylesheet from the source, and that stylesheet contains the detailed font information.
The markup you add to your <head>
section:
<link href="http://fonts.googleapis.com/css?family=Satisfy" rel="stylesheet" />
And what that imports automatically when the page loads:
/* latin */
@font-face {
font-family: 'Satisfy';
font-style: normal;
font-weight: 400;
src: local('Satisfy'), url(http://fonts.gstatic.com/s/satisfy/v5/0EcI1zXfvSXoNHQChcRmRwLUuEpTyoUstqEm5AMlJo4.woff2) format('woff2'), url(http://fonts.gstatic.com/s/satisfy/v5/tmRzDlQs5wZmOn9mIuLa-QLUuEpTyoUstqEm5AMlJo4.woff) format('woff');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
Now the font "satisfy" (only the 400 weight) is available for you to use in your font-family
property.
You can now automatically add another div-like element either before or after the existing element by purely using CSS. This is done with the ::before
and ::after
pseudo-elements. These elements, which should have the content
attribute specified (even if it's blank), can be used to add annotations or stylistic flairs to either side of an existing element.
For example, if we wanted to create a simple footnote notification bubble after a line of text:
p.footnoted::after{
content: "1";
font-size: .5em;
vertical-align: super;
border-radius: .5em; // to make it circular
background-color: lightyellow;
}
This stuff should all be in the territory of "looks interesting, I'll check it out later if I need to". We're including it here so you have an idea of what's out there not so you can start using it right away.
CSS3 provides lots of support for animations, an arena typically reserved for JavaScript. They often cover simple cases and can render more smoothly than equivalent JavaScript animations.
The most common way is by using the transition
property to transition a CSS property from one value to another based on some trigger (like hovering or activating it with JavaScript code). If you really need to get into animations, check out the MDN Animations Guide, but it's a rabbit hole so don't get lost.
It used to be a real pain to add in gradients (think a single pixel image repeating), but now CSS3 lets you specify the properties of the gradient and whether it's meant to be linear or radial. The syntax can be a bit odd so there are all kinds of gradient generators out there to help you out. See Additional Resources for more information.
The basic syntax of a gradient used in a background looks like:
background: linear-gradient(to bottom, blue, white);
If you want to break the interior of a paragraph into 2 columns... just use the CSS columns
property! Shown below with some vendor prefixes:
.container p{
-webkit-columns:3;
-moz-columns:3;
columns:3;
}
CSS3 has several new pseudo-classes which target elements based on their position in the document or their relation to other elements. You shouldn't immediately start using these... this is just to show you what's out there:
<p></p>
.You can pass a comma-delimited list of background properties to actually set multiple layered background images to an element. Designers use this to achieve interesting parallax effects by using JavaScript to animate different backgrounds at different rates while the user scrolls. See the MDN docs for more info.
There's one last important bit that you need to understand in order to effectively implement CSS3. Because each browser does things slightly differently, you'll sometimes have to list the same style multiple times by using the "browser prefixes". Each prefix applies to the primary CSS engine used by a particular browser.
This is a legacy thing -- modern browsers are capable of using the standard properties. For many developers, supporting the old browsers isn't necessary so you don't need to worry about the prefixing. You'll certainly see them in older CSS and older examples on the web.
As an example, a real-world implementation of the box-sizing
property would actually look like the following:
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
Just make sure to put the non-prefixed version last and you're good to go.
Check out this article from CSS-snippets for more information about this and this blog post for a more up-to-date listing of which prefixes are actually needed (as of 2014).
The important bits of code from this lesson
/* Apply only on wider than 500px browsers */
@media (min-width: 500px) { ... }
/* Import this stylesheet only on mobile */
<link rel="stylesheet" media="handheld" />
/* Chain multiple criteria */
@media screen and (min-aspect-ratio: 1/1) { ... }
/* Media Query Types */
@media (min-width: 1100px) { ... }
@media (max-height: 400px) { ... }
@media (min-aspect-ratio: 1/1) { ... }
@media (orientation: portrait) { ... }
@media (color){ ... }
@media (device-aspect-ratio: 16/9) { ... }
@media (max-device-width: 799px) { ... }
@media (max-device-height: 799px) { ... }
@media (grid) { ... }
@media print and (min-resolution: 300dpi) { ... }
/* Make padding and borders push inward */
box-sizing: border-box;
/* Select based on a given attribute */
[attr=val]{ ... }
/* Match parts of an attribute */
[attr^=val]{ ... } // Starts with "val"
[attr$=val]{ ... } // Ends with "val"
[attr*=val]{ ... } // Contains "val"
/* Rounded corners */
border-radius: 10px;
/* Red fuzzy inset shadow */
box-shadow: 2px 2px 2px 0 #f00 inset;
/* Dynamically calculate values (with fallback!) */
width: 90%; /* fallback for browsers without support for calc() */
width: calc(50% - 80px);
/* Import a google webfont */
<link href="http://fonts.googleapis.com/css?family=Satisfy" rel="stylesheet" />
/* Use the imported font (just like a normal one) */
font-family: Satisfy, serif;
/* Put novelty quotes before and after a blockquote */
blockquote:before {
color: #ccc;
content: "<<"; // Can use special UTF chars too
font-size: 4em;
}
blockquote:after {
color: #ccc;
content: ">>";
font-size: 4em;
}
/* Target the first child element */
.parent-class:first-child{ ... };
/* Browser Prefixes (outdated mostly) */
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
Hopefully you pulled some useful tidbits out of these examples. CSS3 has a lot of stuff on top of the already-expansive CSS. Don't worry if you're forgetting things. Remember -- you really learn by building and you'll get plenty of opportunity to do that soon. We also have more detailed lessons on these concepts coming up in this section.
Oh, before we go... the most painful thing you'll do is probably centering elements. Take a glance through this helpful blog post and this code generator before you get too many gray hairs.