Must Watch!



MustWatch



CSS System Font Stack Reference

Fonts on a website can easily become a large part of the total bundle size that browsers have to download before being able to display a page in its final look and form. Plus, we need to worry about all kinds of things like the infamous Flash of Unstyled Text (FOUT). Arguably, though, part of this whole issue has been resolved, thanks to the font-display property. Skip the intro and jump to the font stack reference already! Added to that is the fact that the text found on a website is almost always the most important part, so we don't want text that doesn't look right or that's hard to read. What's a savvy web designer to do to satisfy both performance as well as look and feel? One solution is to actually resort to using a font that's already installed on the device of the user. In the past that was not a very elegant solution because some popular systems didn't come with beautiful font faces baked-in. Things are different now however, and every major operating systems ships with a sans serif system font that looks and reads nice. So the trick just becomes to provide all those default system font names as the value for the font-family property for the element(s) that should use a system font. The browser will then use the first one that it can find on the current system. Keep in mind that this will also mean that the text will look different based on what system it is being read on. That's not necessarily a bad thing however, as the text will feel native to the OS its being read on.

Sans Serif System Font Stack

Without further ado, here's the version of the system font stack used on this very website: body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; } That stack is the same one used with WordPress, and has been working pretty well so far for content on Alligator.io. On this site, the titles use the Recursive variable font for a little bit more panache, but the content itself uses the system font. Here's a breakdown of those fonts/keywords, if you're curious:
  • -apple-system and BlinkMacSystemFont: Keywords used to refer to the system font on Apple devices, usually San Francisco or Helvetica Neue, depending on the version of the operating system. On some newer browsers the keyword system-ui can now be used to do the job of those two keywords.
  • Segoe UI: Used on Windows systems.
  • Roboto: System font for Android devices.
  • Oxygen-Sans: Linux systems using KDE.
  • Ubuntu: Ubuntu Linux
  • Cantarell: Linux systems using Gnome (other than Ubuntu).
  • Helvetica Neue: A common fallback font available on many systems (especially Apple systems), just in case the previous ones all failed.
  • sans-serif: If all else fails, fallback to the default browser sans-serif font. Often not the most pleasing result, hence why we don't just use font-family: sans-serif.
  • As with most things in life, there are many different flavors of the system font stack and each ones varies a little bit. For example, here's the stack that GitHub uses.

    Monospace System Font Stack

    While there's no system font stack for a serif-based font, there's one for a monospace font, which can be really useful for code snippets and such. Here's the one used by Bootstrap v4 (with GitHub using a very similar version as well): code { font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; }

    System Fonts Using @font-face

    In case you're getting tired of repeating the same string of multiple font names at multiple places in your CSS, there's a trick documented in this CSS-Tricks article to allow making use of a @font-face at-rule to define a single name that refers to the whole stack.

    Styling Scrollbars with CSS: The Modern Way to Style Scrollbars

    William Le Since the early days of the web, customizing the browser's scrollbar has proven to be very difficult to standardize across major browsers. Fortunately, on September 2018 a W3C Working Draft called CSS Scrollbars was released that looks like a viable way to finally accomplish this! Styling the scrollbar in the browser can be an valuable way to communicate a company's brand. For example, styling the Alligator.io website's scrollbars could look like this: Throughout the years, there emerged many ways to accomplish this. Microsoft Internet Explorer was one of the first vendors to provide a CSS API for this, but many indie developers were so frustrated to find a solution that they created various solutions with JavaScript. Fast-forward to today, now that Internet Explorer is slowly being replaced by Microsoft Edge, it just boils down to 2 approaches:
  • Chrome/Edge/Safari: using -webkit-scrollbar
  • Firefox: uses the new CSS Scrollbars API (eg., scrollbar-color and scrollbar-width) spec.
  • Let's jump into some code samples! The JavaScript solutions fall short since they have difficulty emulating high-end behaviors like inertia scrolling (eg., decaying motion when scrolling via trackpads).

    Scrollbars in Chrome/Edge/Safari

    Styling scrollbars for Chrome/Edge/Safari is available behind the vendor prefix -webkit-scrollbar body::-webkit-scrollbar { width: 12px; /* width of the entire scrollbar */ } body::-webkit-scrollbar-track { background: orange; /* color of the tracking area */ } body::-webkit-scrollbar-thumb { background-color: blue; /* color of the scroll thumb */ border-radius: 20px; /* roundness of the scroll thumb */ border: 3px solid orange; /* creates padding around scroll thumb */ } But there's good news… And bad news: Good news! This code works perfectly fine in the latest releases of Chrome/Edge/Safari! Bad news? Unfortunately, this spec has been formally abandoned by W3C so we can expect it to be slowly deprecated in the coming years. Microsoft Edge officially switched to the Chromium V8 engine on January 2020!

    Scrollbars in Firefox

    Firefox is a champion of new W3C standards, and they're always willing to try out emerging APIs. As such, the new CSS Scrollbars features are already available in normal releases of Firefox: body { scrollbar-width: thin; /* "auto" or "thin" */ scrollbar-color: blue orange; /* scroll thumb & track */ } Sweet! You might have noticed a few differences compared to the deprecated -webkit-scrollbar spec. Firstly, it's way more concise! And secondly, it lacks features like creating a padding and roundness for the “track thumb”. Since the spec is still changing, these missing features could likely get included.

    The Way Forward

    How do we style scrollbars considering there isn't a single, authoritative API? Just combine both approaches! /* The emerging W3C standard that is currently Firefox-only */ * { scrollbar-width: thin; scrollbar-color: blue orange; } /* Works on Chrome/Edge/Safari */ *::-webkit-scrollbar { width: 12px; } *::-webkit-scrollbar-track { background: orange; } *::-webkit-scrollbar-thumb { background-color: blue; border-radius: 20px; border: 3px solid orange; } Once -webkit-scrollbar is deprecated, you can fallback on the new CSS Scrollbars standard without missing a beat. Interactive demo below: See the Pen CSS scrollbar stylinz by Alligator.io (@alligatorio) on CodePen. Try switching to a different browser to see it working. Supports the latest Firefox/Chrome/Safari/Edge releases Learn more by visiting the MDN for documentation on CSS Scrollbars

    Using the CSS line-height Property to Improve Readability

    William Le In this article, you will learn about the CSS line-height property and how you can use it to create visually pleasant, readable text. You have probably seen line-height being used before: p { font-size: 16px; line-height: 1.2; } But how does it work, and what role does it have in CSS?

    Typographic Roots in CSS

    Many ideas in CSS were drawn from the discipline of typography. One example is the CSS line-height property which sets the distance between two baselines of wrapped text. The “baseline” is the imaginary line that text sits on. For example, if we had this short snippet of text inside a <div> tag: <div> The alligator went for a swim in the deep lagoon. </div> If you dragged your browser window so the text wrapped to the next line, you'd have two baselines and a line-height (denoted by the yellow arrows): A larger value for the CSS line-height property will expand this distance, and smaller values will shrink it.

    Line Height & Text Readability

    The line-height property plays a central role in making text readable for users. When you undersize line-height it will feel crowded. Reading text like this for extended periods will feel exhausting to the user: If it's too large, the user will have difficulty feeling engaged with what they're reading: But when you find the right line-height, your text will feel spacious and harmonious Finding the right line-height will vary based on your needs, but it also depends on the font family that you're using. This is because each font has its own personality and will “read” differently in a substantial block of text. For example, Helvetica and Times New Roman will require different line-height spacing even if they both have the same font-size.

    Syntax for line-height

    You can provide line-height with all sorts of values! It's also quite distinct from other CSS properties because it can accept typical px and % values, but it also has its own unique “unitless” value: /* Use browser default. Typically "1.2" for all the major browsers */ line-height: normal; /* Unitless (only line-height can do this!) */ line-height: 1.2; /* <length> values like px, rem, em, pt */ line-height: 3em; /* <percentage> values */ line-height: 120%; The line-height is denoted by the yellow arrow.

    How Browsers Compute line-height

    If you use a percentage or “unitless” value the font-size will be factored into the resulting line-height. For example, both snippets below will compute to 19.2px by the browser: .myText { font-size: 16px; line-height: 1.2 /* (19.2px = 16 x 1.2) */ } .myText { font-size: 16px; line-height: 120%; /* (19.2px = 16 x 1.2) */ } However, if you use “length” values like px|em|rem|pt, the font-size won't be used to calculate the line-height: .myText { font-size: 16px; line-height: 20px; /* Always 20px! */ } While both percentage and "unitless" values seem to be identical, there are subtle differences. Best practices suggest using "unitless" values whenever possible

    Conclusion

    Generally speaking, a good line-height ranges between 1.5 and 1.7 for most fonts. Alligator.io, for example, uses a line height of 1.6. It's more art than science, and many times you'll find yourself opening your browser's “Developer Tools” to nudge the line-height until it feels “just right”

    How to Use the CSS :root Pseudo-Class Selector

    William Le Learn about the CSS :root pseudo-class selector, and how you might want to use it in your projects! The CSS :root pseudo-class selector is used to select the highest-level parent of a given specification. In the HTML specification, the :root is essentially equivalent to the html selector. In the CSS snippet below the :root and html styles will do the same thing: :root { background-color: gray; } html { background-color: gray; } If you noticed I said :root is essentially equivalent to the html selector. In fact, the :root selector has more authority than html. This is because it's actually considered a pseudo-class selector (like :first-child or :hover). As a pseudo-class selector, it has more authority/higher specificity than tag selectors: :root { background-color: blue; color: white; } html { background-color: red; color: white; } Despite the html selector coming after, the :root selector still wins, thanks to its higher specificity!

    Cross-Specification

    In the HTML specification, the :root pseudo-class targets the highest-level parent: html. Since CSS is also designed for SVG and XML you can actually use :root and it will just correspond to a different element. For example, in SVG the highest-level parent is the svg tag. :root { fill: gold; } svg { fill: gold; } Similar to HTML, the :root and svg tags select the same element, however the :root selector will have higher specificity.

    Practical Uses

    What are the practical uses for :root? As we covered earlier, it's a safe substitute for the html selector. This means you can do anything you'd normally do with the html selector: :root { margin: 0; padding: 0; color: #0000FF; font-family: "Helvetica", "Arial", sans-serif; line-height: 1.5; } If you'd like, you can refactor this code to use CSS Custom Properties to create variables at the global level! :root { margin: 0; padding: 0; --primary-color: #0000FF; --body-fonts: "Helvetica", "Arial", sans-serif; --line-height: 1.5; } p { color: var(--primary-color); font-family: var(--body-fonts); line-height: var(--line-height); } The added benefit of using :root instead of html is that you can style your SVG graphics! :root { margin: 0; padding: 0; --primary-color: #0000FF; --body-fonts: "Helvetica", "Arial", sans-serif; --line-height: 1.5; } svg { font-family: var(--body-fonts); } svg circle { fill: var(--primary-color); }

    When Should You Use the CSS !important Rule?

    William Le The !important rule in CSS gives you the ability to override styles, but is this power too much for a lone software developer? Read this article to find out what it is, and when it's a good idea to use it! The !important rule is special because it has the ability to override the natural cascade of CSS styles. Consider the following HTML/CSS code… What color do you think the text will be? <div> <h1>Sir Chompsalot</h1> </div> div h1 { color: blue !important; } div h1 { color: green; } Normally, if we have two CSS rules with identical specificity the latter rule would win. In this case, the earlier CSS rule beats any latter rules simply because it has the powerful !important rule. The text is blue! Using the same HTML markup, what if we got even more specific by targeting the body tag and h1#title? div h1 { color: blue !important; } body div h1#title { color: green; } Will this have the ability to override the !important rule? Nope! Wow, the !important rule is almost too powerful for its own good.

    Since !important contradicts the expected behavior of CSS, it's generally recommended to avoid using it. If you rely on !important too often it can cause a lot of unexpected behavior down the road, and new developers will have a hard time debugging their CSS. Why isn't this text changing color! Does this mean you should never use it?

    Occasions to Use !important

    As time has passed since !important was introduced to CSS there seems to be some consensus that it's really only useful for a single job: dealing with foreign CSS. Foreign CSS is essentially any CSS that you don't have direct ability to change or improve yourself. Two practical instances of foreign CSS are:
  • JavaScript Frameworks & External Libraries: This applies to popular libraries like Bootstrap, or Normalize. Since you can't edit their CSS styles directly, sometimes your only option is override their CSS with your own !important rules.
  • User Styles: This used to be very popular years ago. User Styles provides a way for you to create your own CSS to inject on websites owned by other people/companies. For example, this dark theme for instagram.com
  • Since foreign CSS can't be changed by you (unless you take a job at Instagram to rectify their serious lack of a dark mode), the !important rule is really your only, and best option. The folks at Mozilla Developer Network and CSS-Tricks seem to agree that !important is really only useful for dealing with foreign CSS

    Conclusion

    If you are really tempted to use !important, try reflecting on architectural decisions that you can make. Not just your CSS either. This could mean adding new HTML tags, or applying new classes/ids. Engaging in this architecture-centric practice results in high quality code that's a joy to maintain! Have you found other appropriate uses for !important? Tweet us at @alligatorio and share it with us!

    The Mighty CSS z-index Property

    William Le In this article, you'll learn about how to use the z-index CSS property… The only way to break into the 3rd dimension with CSS! Most of the time when you're styling things with CSS, it's on a 2D plane. HTML elements are placed horizontally/vertically on the page like stacking blocks in Tetris. The z-index changes this paradigm and gives you the ability to define a visual hierarchy on the 3rd plane: the z-axis.
    In this code snippet, the #navbar, will overlap the #footer (if their position overlaps) because it has a higher z-index. #navbar { position: relative; z-index: 11; } #footer { position: relative; z-index: 10; } If we weren't using z-index at all, the navbar would simply push the footer away instead of overlapping it.

    Uses for z-index

    Looking at code by itself is a little bit abstract, so let's check out this demo where z-index is used. <div> <div><img src="womens-outerwear.jpeg"/></div> <div>Fashion Catalog 2030</div> </div> #portrait { position: relative; z-index: 1 width: 200px; } #magazine-title { position: relative; z-index: 2; top: -2em; left: 2em; font: normal 2em sans-serif; color: darkslategray; background-color: whitesmoke; border: 3px dotted darkslategray; } Using z-index, we're able to cause the text to overlap the image! This is just a small way that layers introduce a different way for you to think about web design. Images are kindly provided by the Unsplash (unsplash.com) community of photographers.

    A Minor Caveat

    If you have a keen eye, you probably noticed that the previous code snippets used position: relative along with z-index. This was not a coincidence: the z-index rule only works on “positioned elements”. Forgetting to apply a position rule will effectively ignore the z-index rule. div { position: static | relative | absolute | sticky | fixed; z-index: 1; } A positioned element is an HTML element that's either relative, absolute, fixed, or sticky. Basically, it's anything besides static.

    Sibling Rivalry

    Another small note is that z-index only competes amongst sibling HTML elements. Given two HTML elements, the deeply nested HTML element will always get overlapped by a less-nested HTML element with a lower z-index value. Here is a demo demonstrating that z-index only competes among sibling HTML elements: <div class="blue"> <div class="violet"></div> <div class="purple"></div> </div> <div class="green"></div> .blue { position: relative; z-index: 2; background-color: blue; } .violet { position: relative; z-index: 4; background-color: violet; } .purple { position: relative; z-index: 1; background-color: purple; } .green { position: relative; z-index: 3; background-color: green; top: -4em; } The HTML element div.violet will get overlapped by div.green despite having a higher z-index value! The values for z-index must be an positive/negative integer. This doesn't mean you can have unlimited z-axis layers! The maximum range is ±2147483647. In CSS code bases, you'll often see z-index values of 999, 9999 or 99999. This is a perhaps lazy way to ensure that the element is always on top. It can lead to problems down the road when multiple elements need to be on top. Most of the time you'll find that a z-index of 1 or 2 will suffice for your needs.

    Wrapping Up

    Let's review some of the things we've learned about z-index:
  • z-index can create overlapping layers on the z-axis!
  • z-index only works with positioned elements
  • z-index only competes with siblings HTML elements
  • When you layer content it can create interesting designs! Hopefully you've gotten a good idea of how z-index works, and some of the guidelines so you can use it with success!

    Introduction to CSS Counters

    joshtronic Counters are a big part of programming. They help keep tabs on loops by storing the number of times it's been executed. Common variable names for increment counters are i, j and k. Before the days of modern CSS, keeping track of things on the page was either done manually in the markup, or by using JavaScript to tally things up. These days are long gone as CSS has a well supported counter property that makes things easy.

    Numbering Sections of a Page

    To get started with counters, imagine you have a page that has multiple <section> tags, each with it's own heading <h3> and content. That page may look something like this: <section> <h3>Ratings</h3> Insert a table with reptile ratings on it... </section> <section> <h3>Alligators</h3> Insert awesome facts about alligators here... </section> <section> <h3>Turtles</h3> Insert interesting facts about turtles here... </section> <section> <h3>Snakes</h3> Insert sketchy facts about snakes here... </section> If you wanted to number each <section> you could simply prefix each <h3> with the number right in the markup. While a great solution when you have a small fixed number of sections, things fall apart quickly when you have tens or even hundreds of sections. The complexity compounds quite quickly the moment you need to reorder the sections. To alleviate this burden, we can use CSS counters. The first step to using CSS counters is to initialize a counter, which sets the value to zero 0: body { counter-reset: sections; } For each section, we will want to increment the counter by 1: section { counter-increment: sections; } To use the counter's value, we can use the content property to prepend the value to the heading h3: h3:before { content: counter(sections) ". "; } Now we'll have section headings like 1. Ratings and 2. Alligators. That's not all, the counter is impervious to adding and removing new sections as well as reordering them!

    Counting the Number of Rows in a Table

    Counting the number of rows <tr> in a <table> is quite similar to how we added a numerical value to each section on the page. The big difference will be that we are only interested in the total value, and not the value for each row. Before we can tally up the rows in a <table>, we will need a <table> to work with: <table border="1" cellpadding="5"> <thead> <tr> <th>Reptile</th> <th>Rating</th> </tr> </thead> <tbody> <tr> <td>Alligator</td> <td>9001</td> </tr> <tr> <td>Turtle</td> <td>223</td> </tr> <tr> <td>Snake</td> <td>3.14</td> </tr> </tbody> <tfoot> <tr> <th>Rows</th> <th class="total"></th> </tr> </tfoot> </table> Note the use of <thead>, <tbody> and <tfoot>. While not necessary, by grouping the rows into sections, we can better target just the rows in the <tbody> section and omit any rows in the header or footer. Same as before, we will want to initiate a counter with a zero value: body { counter-reset: rows; } For each row <tr> in the <tbody> we shall increment the counter: table tbody tr { counter-increment: rows; } Finally, we will add the total number of rows, the final value of the counter, to the footer in the column aptly classed as .total: table .total:before { content: counter(rows); } Now our <table> will report on how many rows it contains. Adding or deleting rows to the markup will yield an updated total. This even works when using JavaScript to manipulate the DOM.

    Conclusion

    Even though we're blurring the line between content and design, counters in CSS are extremely useful and in many cases can completely eliminate the need of introducing JavaScript to a page. Want to see the code snippets on this page in action and play around with it on your own? Check out the code from this post on CodeSandbox.

    Tricks for Using CSS translateZ() and perspective()

    William Le In this article, you'll learn how to use the CSS translateZ() function. In many ways it's a unique CSS function because it challenges the idea that the web page is just a 2D visual space. The CSS transform property has a lot of functions for moving HTMLElements around. Among them are the translateX, translateY, and translateZ functions. While translateX and translateY are pretty straightforward, translateZ is slightly more difficult to understand.
    Let's review how translateX and translateY work: div#myCircle { background-color: gray; width: 20px; height: 20px; border-radius: 100%; transform: translateX(11px) translateY(20px); } The HTMLElement is moved 11px to the right, and down 20px. It's moving it along x-axis and y-axis. You may remember these terms from Math classes in high school! Guess which axis the translateZ function moves? That's right! The z-axis. Instead of moving HTMLElements horizontally/vertically it moves them closer to you, or further away from you.

    Using translateZ()

    Let's try adding translateZ to the previous code snippet: div#myCircle { background-color: gray; width: 20px; height: 20px; border-radius: 100%; transform: translateX(11px) translateY(20px) translateZ(75px) perspective(200px); } You might have noticed another CSS function called perspective(). It's actually required for translateZ to take effect. It's common to forget it since neither translateX or translateY require it… But you gotta remember to use it with translateZ!

    What does perspective() do?

    The perspective() function defines the virtual distance between the plane of your computer screen and the HTMLElement you're applying translateZ to. This means perspective(200px) and translateZ(75px) creates a virtual space of 200px between the HTMLElement and the computer screen, and then moves it 75px closer to you. This causes the HTMLElement to appear larger Likewise using a negative value in translateZ() moves it further away: div#myCircle { background-color: gray; width: 20px; height: 20px; border-radius: 100%; transform: translateX(11px) translateY(20px) translateZ(-100px) perspective(200px); }

    Demo Time

    Here's a small demo that uses the translateZ CSS function. Try hovering your mouse over the buttons! button { /* abridged css values */ transform: perspective(100px) translateZ(0px); transition: transform 100ms linear; } button:hover { transform: perspective(100px) translateZ(5px); } It's really easy to create compelling visual effects using translateZ!

    Interesting Factoids about translateZ()

    There are some unexpected behaviors with perspective and translateZ to keep in mind.
  • If the value provided to translateZ() is equal or higher than the one provided to perspective(), it causes the HTMLElement to disappear. You can always set an infinitely lesser value in translateZ() but the inverse is not true… Once you exceed the value of perspective() the element will no longer be visible.
  • Applying perspective(0px). Any value for perspective() will work… unless it's a zero value (like 0px, 0, 0em). This causes any translateZ() effects to be ignored.
  • Conclusion

    Using translateZ is the stepping stone to seeing webpages as a 3D visual space… not just 2D! Hopefully you'll add it to your toolbox and it'll help you create compelling designs! Visit MDN for documentation on translateZ and perspective

    Comparing CSS Pseudo-Classes: nth-child vs nth-of-type

    Jess Mitchell CSS has a number of pseudo-classes to help you style your app with ease. Having lots of options can be great, but it can also be confusing to know which pseudo-class to use and what it really does. Here we'll look at CSS's nth-child and nth-of-type pseudo-classes to get a better understanding of when to use each and what the actual difference is. The nth-child and nth-of-type CSS pseudo-classes are interesting compared to other types of pseudo-classes because they select elements based on their position in the DOM. Whereas some pseudo-classes select a specific state of an element (e.g. the hover, active, target pseudo-classes), nth-child and nth-of-type are more concerned with the structure of your markup.

    Setting Up Our HTML

    To understand the difference between nth-child and nth-of-type, let's first build our HTML to know what we're going to be styling. Let's say we have a section on our webpage that has a mix of header (<h1>, <h3>) and paragraph (<p>) elements. <article> <h1>Here's a Header</h1> <p>I'm a paragraph with all kinds of information.</p> <p>Let's add another paragraph for fun.</p> <p>yadda yadda yadda</p> <p>blah blah blah</p> <p>yadda yadda yadda</p> <h3>Here's a Subheader</h3> <p>blah blah blah</p> <p>And maybe just one more.</p> </article> This markup will look something like this: In total, we have an <article> element as the parent, and nine child elements: one <h1>, one <h3>, and seven <p> tags.

    nth-child and nth-of-type Syntax

    There are a few options for what values you can pass the nth-child and nth-of-type pseudo-classes. Note: nth-child is used here but it can be replaced with nth-of-type too.
  • :nth-child(2n+3): This option requires some math. The numbers are up to you; it's the n that will vary. This will take your selected elements, set n to 0 to start, and increment from there. So, similarly to a for loop in JavaScript, it will iterate through your selected elements by updating the n value: 2(0)+3 = 3, 2(1)+3 = 5, 2(2)+3 = 7, and so on. The result of this will be selecting the third, fifth, seventh, etc. elements.
  • :nth-child(odd/even): The strings odd or even can be passed to select the odd and even elements available.
  • :nth-child(3n): You can also pass a number with the n variable, which will select that interval of the selected element's occurrence. If 3 is passed, it will select the third, sixth, ninth, etc. elements.
  • :nth-child(3): If you just pass a number (without the n), it will select that element from the DOM specifically. Passing 3 will select the third matching element only.

  • Using CSS's nth-child Pseudo-Class

    The nth-child pseudo-class has two important components to consider:
  • the element(s) selected that will have the pseudo-class applied to it/them
  • the value passed to the pseudo-class.
  • If we go to our CSS stylesheet for the HTML example above, we can select our paragraph elements and make the font color maroon like so: article p { color: maroon; } Let's say we want every other paragraph element to be a yellow-ish color, though. (An “interesting” style choice… ) We can apply the nth-child pseudo-class to only apply the new color to every other child element that's a paragraph. article p:nth-child(odd) { color: goldenrod; } Now our paragraphs alternate colors, but did you notice what happened after the sub-header? The maroon color was repeated and then switched back to yellow. Let's look at why that happened.

    Determining Which Elements are Selected with nth-child

    In our example above, the paragraphs that match our p:nth-child(odd) styling have to meet the following requirements in this order:
  • they are an odd child of the parent element
  • they are a paragraph element
  • Determining whether the child is odd or even is not type-specific. That means the odd/even check looks at all the children in the parent element of what is being selected (the paragraph elements) and then looks for all the paragraphs that are considered odd elements. The paragraphs that have the yellow font styling applied are “odd” children elements and they are paragraph (<p>) elements. That explains why the paragraph after the sub-header ends up being the default maroon color– it's actually an “even” child!

    Using CSS's nth-of-type Pseudo-Class

    The nth-of-type is very similar to the nth-child pseudo-class. The main difference is that it specifically considers the type of the element getting selected before checking any other logic. Let's use our example from above but apply nth-of-type instead. <article> <h1>Here's a Header</h1> <p>I'm a paragraph with all kinds of information.</p> <p>Let's add another paragraph for fun.</p> <p>yadda yadda yadda</p> <p>blah blah blah</p> <p>yadda yadda yadda</p> <h3>Here's a Subheader</h3> <p>blah blah blah</p> <p>And maybe just one more.</p> </article> article p { color: maroon; } article p:nth-of-type(odd) { color: goldenrod; } The default color is still maroon but now we're selecting the odd paragraph elements only. The styles are now applied if the element meets the following requirement:
  • the element is a paragraph with an article element as a parent
  • of the paragraphs selected above, only odd ones are selected
  • If we look at this again with the annotations, it's a little clearer how these are getting selected. The headers (<h1>, <h3>) are not considered at all with nth-of-type because we're selecting by the element type specifically. We only care about the <p> elements in this case.
    Whether you use nth-child or nth-of-type will ultimately depend on what your goal is for styling. (Classic “it depends” answer, right? ) As a general rule, if you want to select an interval of a selector regardless of the type of element it is, use nth-child. However, if you want to select a specific type only and apply an interval selection from there, use nth-of-type.

    Browser Support

    The nth-child and nth-of-type selectors both have excellent browser support. Check nth-child and nth-of-type on CanIUse.com for more details. You shouldn't have any issues with either unless you're supporting IE8 or lower.

    CSS Hex Code Colors with Alpha Values

    Jess Mitchell In CSS, there are several formats for colors that can be used. Common ones include RGB, RGBA, hex codes, and HSL. Here we'll review hex (hexadecimal) color codes and specifically look at changing the transparency of the color by introducing an alpha value too.

    What Is a Hexadecimal Number?

    Before we get to the CSS-specific tips, let's first review what a hexadecimal value means. The word “hexadecimal” refers to a numerical value that uses 16 as a base instead of 10. Using a base of 10 is what most people are used to; after 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 comes 10. In others words, a single digit only has 10 possible values (0 to 9), and after that it must increase to two digits (10). A hexadecimal value can have 16 values for each digit in a number: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F In effect, it means numbers with multiple digits have many more possible combinations. A two digit value in base 10 can have 100 possible combinations (00, 01, 02… 66, 67, 68… 98, 99). However, using a two-digit hexadecimal value has many more possible combinations. Since each digit can have 16 possible values, the total possible combinations for a two-digit number is 16 x 16 or 256 possible values. For example, these are all valid hexadecimal values: 00, 01, 1D, 9D, F5, 99, E4, CC We'll leave it at that for the math portion. Let's move on to the CSS.

    Using Hexadecimal Values in CSS

    When styling an element in CSS, we'll often need to update the colors related to it. That could include font color, background-color, border-color, etc. To create custom colors, we can use combinations of the hexadecimal numbers described above to create hex codes, which represent specific colors. CSS hex codes are not case-sensitive, so you can use upper- or lowercase values. Often there will be a preference in a codebase for consistency.

    But First, Named Colors in CSS

    The simplest way to set the color is to just use named colors. Named colors in CSS are valid color names that can be used directly in your CSS styles. For example, if we wanted our header text to be red, we could literally just write red like so: h1 { color: red; } There are about 140 named colors in CSS (like red, blue, lavender, etc.) that can be used to avoid figuring out things like the hex codes. So, why use hex codes? Simply, there are many more options if you want to really customize your app's color palette! Plus, you can change the transparency more easily.

    Hex (Hexadecimal) Codes in CSS with No Alpha Value

    The format of the CSS hex code is #RRGGBB. The letters refer to red (RR), green (GG), and blue (BB) so you can think of the 6-character value as being three two-digit hexadecimal numbers; one for each of the three colors. Don't forget: in CSS, you need to use the pound/hash symbol (#) before your hex code for it to be valid. Now that we know our format (#RRGGBB), let's look at some examples of CSS colors in their hexadecimal format. Each color you pick will be a combination of a red, green, and blue value. The lowest value (00) will be the darkest version of the color (closest to black), and the highest value (FF) will be closest to white. If we want to only have one of those colors represented in our hex code, we can set the other ones to the lowest value (00). Let's say we wanted the brightest red with no green or blue in it. We can set our red (RR) value to the highest possible value (FF). Since we don't want any green or blue in it, we can set the green (GG) and blue (BB) values each to 00 (the lowest value). h1 { color: #FF0000; // bright red } This will look like:

    I'm bright red!

    Since hexadecimal numbers are in base 16, the lowest value for a two-digit number is 00 and highest value is FF. The lowest value will have the most black in it. Similarly, we could say we want no color, which in this case would make the color black. h1 { color: #000000; // black } If we put all the colors at their highest value, we get white. h1 { color: #FFFFFF; // white } From there, any other combination will give you an entire spectrum of color options. Don't worry about learning how to pick the hexadecimal values yourself. There are tons of resources for picking colors that will do the hexadecimal conversion for you!

    Adding an Alpha Value to Your Hex Codes

    Now that we know what hex codes are, let's look at changing the transparency of our colors. Let's say we want a blue color that is fairly transparent. We can first select our color of blue: h1 { color: #0080FF; // cornflower blue } This color will look like this:

    I'm blue!

    Now, let's say we want our text to be semi-transparent, we can change the transparency by adding two more numbers to our hexadecimal value (also known as the alpha value). h1 { color: #0080FF80; // transparent blue } Now our color will look like this:

    I'm transparent blue!

    Wait, what?

    So, what's going on here? Let's break it down. Using an alpha value to update a color's transparency will change the hex code format from #RRGGBB to #RRGGBBAA (red, green, blue, alpha). The first six values (the red, green, and blue ones) stay the exact same. The only difference is the last two values (the AA). The AA value in #RRGGBBAA can range from the lowest value possible (00) to the highest value possible (FF). The lowest will make the color fully transparent, which means you won't see it anymore. The highest value will make it completely opaque, which is the default for hex codes anyway. Partially transparent: #0634a477 Fully Opaque: #0634a4ff The alpha value in the hexadecimal format can be a little confusing because it's hard to conceptualize what a base 16 value for transparency will actually look like. However, the benefit is if you're already using hex codes in your codebase, now you can update them to change the transparency too! No color format changes required.

    Comparing Hex Code+Alpha Format to RGBA

    If you've had to set the transparency of a color before, you may know there are a few different options. The RGBA color format, for example, is one option instead of hex codes with an alpha value. The RGBA format looks like this: h1 { color: rgba(256, 0, 0, 0.5); // transparent red } Each color value (red, green, blue) in the RGBA (Red, Green, Blue, Alpha) format can range from 0 to 256. Unlike hex codes, though, only base 10 numbers are valid (0, 1, 2…255, 256). For the alpha value, any number from 0 to 1 is valid. Think of it as a transparency percentage: 0.5 is 50% transparent, 0.75 is 75% transparent, etc. The closer the number is to 1, the more opaque the color will be. If number 256 looks familiar here, remember there are 256 valid values for each two-digit hexadecimal number (16 x 16). The RGBA format also accepts 256 valid numbers (plus 0) for each of the red, green, and blue values. That makes hex codes and RGB/RGBA values easily convertible!

    Chrome DevTools Tip for Color Pickers

    Color formats can already be confusing enough before adding the alpha value too. One quick tip for seeing your colors in different formats is with the Chrome DevTools. Once your DevTools panel is open, look for the color your checking in the styles section. Once you find it, you can click the box to the left of the color to play around with it directly. You can also hold SHIFT and click on the box to toggle through your various format options with the values correctly converted. (The example above is inspecting a Google search result page.)

    CSS Color Resources

    Here's a great tool for converting colors to all the different formats. If you're curious what the hex codes for CSS named colors are, check them out here. ## Browser Compatibility The browser support for #RRGGBBAA hex codes is great. IE doesn't support it but otherwise you should be covered. Check Can I Use for details if you're curious.

    Understanding Specificity in CSS

    Jess Mitchell Specificity in CSS refers to the how browsers determine the importance, relevance, and “seniority” of CSS styles. Here we'll look at all the CSS styling types and use the company analogy to understand how competing styles get resolved.

    CSS Selector Overview

    There are multiple ways to select the elements you're trying to style in CSS. Let's start by reviewing all the options.
  • Type Selectors: Select your intended element by using its element type. For example, to select all your <p> tags, use p in your CSS style sheet.
  • Pseudo-Elements: As the name suggests, pseudo-elements are not elements themselves but allow you to select part of your HTML relative to another selector. For example, select the first letter of each paragraph with p::first-letter.
  • Class Selectors: Elements can have multiple classes set on them to be selected in your CSS style sheet. For example, <h1 class='header'> can be selected with .header. Multiple elements can have the same class applied to them.
  • Attribute Selectors: Select elements that have a specific type of attribute applied to them. For example, select inputs that accept numbers only with input[type='number'].
  • Pseudo-Classes: Select elements based on the CSS state they're in. For example, style the hovered state of a button with button:hover. Check out these previous tutorials on the :target, :hover and :active pseudo-classes to learn more.
  • ID Selectors: Select a specific element with its unique ID. There can only be one element with each ID, whereas classes can be applied to multiple elements. For example, select <h1 id='mainHeader'> with #mainHeader.
  • Inline Styles: Inline styles are applied to elements directly with the style attribute so you don't actually use any CSS selectors. For example, you can make your header font color blue directly with <h1 style='color: blue;'>
  • CSS Selectors and Their “Weights”

    Each type of selector listed above has a weight. All of these can be divided into four main groups:
  • lowest weight: type and pseudo-element selectors
  • low weight: class, attribute, and pseudo-class selectors
  • medium weight: ID selectors
  • high weight: inline styling
  • If styles of differing weights are applied to the same element, the styling with the higher weight will be applied. If styles of even weights are applied, the styles that come last (nearest to the end of your style sheet) will be applied. This is due to the “cascading” effect of CSS (Cascading Style Sheets). For any element being styled, the last applicable block of styling with the highest weight will be applied to your element. Inline styling will trump CSS selector styling, though. When two selectors of the same weight are applied to an element, it counts as 2x the weight. So, for example, an element selected with two classes will have a higher weight than just one in your CSS. .gator.cayman { // two classes color: purple; } .gator { // one class color: purple; } The main issue most of us web developers will face at some point is having multiple styles that interfere with each other. If you use a CSS framework, like Material UI, you may be trying to override some default styles. Alternately, you could have an old (and disorganized ) styles.css file where you keep having to increase specificity because it's not clear why your styles aren't getting applied as expected. Like anything in web development, understanding your tools well will lead to them being used more accurately. Let's take a look at how different combinations of selectors impact specificity and some tricks to get your styles applied as intended.

    The Problem with Competing Selectors

    Understanding that different selectors have different weights is crucial for getting your CSS organized. But what if it's not clear what has a higher weight? Let's say we have a paragraph that has two completing blocks of CSS: one with three matching classes and another block with a type attribute and two matching classes. For example, let's take this input with three classes and a number type attribute applied to it. <input type='number' class='gator cayman reptile'> If we apply these competing selectors (three matching classes vs. two matching classes and an attribute), which one will get applied? .gator.cayman.reptile { color: purple; } [type='number'].gator.cayman { color: green; } In this case, the “weight” of both blocks is completely even. Attribute selectors and class selectors have the same weight and each block has three of them in total. Since they're even, we rely on the cascading effect of CSS. The last one gets applied and the input font color will be green. This gets a little more complicated when you have selectors of different weights getting mixed, though. Let's update our input to have an ID, which has a higher weight than classes and attributes. <input type='number' id='gatorInput' class='gator cayman reptile'> If we have competing styles again and use the ID for one and the classes/attribute for the other, which will get applied? #gatorInput { color: purple; } [type='number'].gator.cayman.reptile { color: green; } In the first block, only one ID is being used to apply the styling. In the second block there are three classes and an attribute selector, and it comes last. Even though there are more selectors in the second block, the ID selector has a higher weight and the text will be purple! Selectors with a higher weight will always trump those with a smaller weight, even if there are multiple selectors of a lower weight.

    Selector Weight Trick

    One trick (okay, hack ) in CSS when you just need a little more weight is repeating a class in the same block of CSS. input.gator.gator { color: purple; } input.gator { color: green; } It might surprise you to know that the first block has a weight of two classes and the second block has a weight of one class, even though the first just repeats the class .gator. Because two classes has a higher weight than one, the input text will be purple! You shouldn't ever need to use this trick in production-level code because it's an indicator that you have styles of very similar weights competing. Ideally, you should resolve those styles to be more clearly defined. However, this is a nice tool in your CSS toolbox when you're in a "just make it work" mode.

    The Company Analogy for CSS Specificity

    Specificity can sometimes feeling counter-intuitive, especially if you're stuck in a downward spiral of adding more and more selectors to your CSS. One way I find helpful to think about specificity is by thinking of a company with clear seniority levels. Here are our company's roles in order of seniority (low to high):
  • employees
  • managers
  • directors
  • VPs
  • one CEO (we'll come back to the CEO in a bit)
  • Let's map these roles to our selectors now:
  • employees: type and pseudo-element selectors
  • managers: class, attribute, and pseudo-class selectors
  • directors: ID selectors
  • VPs: inline styling
  • Let's look at a new example. In this case we have a paragraph with two classes and an ID. <p id='gatorParagraph' class='gator reptile'> blah blah blah </p> #gatorParagraph { color: purple; } p.gator.reptile { color: green; } We have one block that uses an ID only and another block that uses an element type (<p>) and two classes. At first glance it could be hard to know which one will get applied. If we use our company analogy, we have one director saying to make the text purple. On the other hand, we have an employee and two managers saying to make it green. Because the director has the highest seniority, she can trump the employee and managers' opinions. So the text has to be purple! (No comment on whether this is how decisions should be made at the company ). Consider each weight level a way of escalating the decision of which styles to apply. If it can't be decided by the selectors on the same level, escalating it will give the decision to the selector of higher seniority. As a general rule, it's best to write CSS that is specific enough you're not going to have to find ways to keep escalating it. Be aware that once you introduce a new level of seniority, like an ID, you could be overriding other styles unintentionally too.

    !important is the CEO

    So far we haven't discussed who our company's CEO is in this analogy for CSS specificity. What's higher than inline styling? The !important rule! Using our same example as before, let's add !important to the block that previously had a lower weight/seniority. #gatorParagraph { color: purple; } p.gator.reptile { color: green !important; } Adding !important will always escalate the seniority to be the highest possible level. With our company analogy, we now have a director vs. an employee, two managers, and the CEO. As soon as the CEO is introduced, she can trump anything else being suggested.

    Please Don't Use !important

    The !important rule is a slippery slope and seeing it in your CSS styles is generally a red flag that the specificity needs to be reorganized. It is rare that there will be an element that can only be styled by nuking the rest of your CSS rules that would otherwise be applied. Once you introduce !important, it often leads to being overused like in the example below. The !importants cancel each other out and you're back to having to understand the weight and cascading effect of each block. #gatorParagraph { color: purple !important; } p.gator.reptile { color: green !important; } Instead of using the !important rule, try opening your dev tools in the browser to get a better understanding of which styles are interfering with your new ones. Once you know what styles are causing you trouble, you can either add additional selectors of the same level of weight, or update your markup to use different selectors. Using !important will often inevitably lead to having competing CSS styles that both use !important.

    Universal Selector and Combinators

    The universal selector (*) and combinators do not impact the weight of your selectors. Combinators include child selectors (>), general sibling selectors (~), and adjacent sibling selectors (+). For example, if we have a paragraph with two spans, using a child combinator will not increase the specificity over not using it: <p id='gatorParagraph'> <span class='reptile'>eggs</span> <span class='reptile'>nest</span> </p> #gatorParagraph > .reptile { color: purple; } #gatorParagraph .reptile{ color: green; } These blocks of CSS has the same specificity – the child combinator makes no difference – so the text will be green.

    Helpful Links

    One of the best visuals for understanding CSS specificity is called specifishity, by Estelle Weyl. Check it out! Also, if you're not keen on adding up specificity weights yourself, there's a specificity calculator that will do the math for you.

    Change Text Case with CSS's text-transform Property

    Jess Mitchell CSS's text-transform property offers a simple way to change the case of your text. It's a small but helpful tool that'll make sure you never have to worry about hard-coding text in a specific case. Here we'll take a look at all your text-transform options and some examples of when you'd use them. The text-transform property has six main values:
  • capitalize
  • uppercase
  • lowercase
  • none
  • initial
  • inherit
  • It can be applied to any CSS selector and will update the text case of any elements it is applied to.

    Capitalize

    h4 { text-transform: uppercase; } In this case, all h4 elements will be converted to uppercase. For example, let's take an h4 element with no other styling applied to it: <h4>Learning with Alligator.io </h4> Without the text-transform property, we'll get this:

    Learning with Alligator.io

    To transform this text, we can apply the CSS block shown above and get this instead:

    Learning with Alligator.io

    Since we declared uppercase as our text-transform value, our entire string value for the h4 element is converted to uppercase. It's as easy as that! Using the value capitalize is the one option that may show some differences across browsers. This is because determining the first “letter” for each word in a string has some discrepancies between browsers. Symbols, like @ for example, may be considered a letter in one browser but not another. This issue doesn't happen with the other values because the letters are either all uppercase or all lowercase; the position of the letters doesn't matter. Now let's take a look at the other values and how they transform our h4 element.

    Lowercase

    h4 { text-transform: lowercase; }

    Learning with Alligator.io


    Capitalize

    h4 { text-transform: capitalize; }

    Learning with Alligator.io


    None

    h4 { text-transform: none; }

    Learning with Alligator.io

    If you're wondering if anything is different with this one, it's not! none will not change your text's original case. You can use none to override other styling. For example, if you're using a CSS framework (like Bootstrap), you could override its default CSS settings with none.

    Inherit

    Using the value inherit will cause the element being selected to get its parent's text-transform value. If the parent does not have a text-transform value set, it will have the default value applied (none). header { text-transform: capitalize; } header h4 { text-transform: inherit; } In this case, any h4 element that is a child of a header element will have the text-transform value of capitalize.

    Initial

    In CSS, initial refers to the initial value of the element. Since the initial value of elements for text-transform is none, using initial will have the same effect as using none.

    Using CSS Instead of JavaScript

    If you've written any JavaScript, you may have come across the two case-related methods: .toLowerCase() and .toUpperCase(). These are great when you're trying to standardize the format of strings, especially if there's a value comparison that should be case insensitive. However, they can get overused. One situation where you may not need to update your strings in your JavaScript code is if a case change is for stylistic purposes. For example, if you want all your headers to be uppercase, you can apply CSS's text-transform property to all your headers. It's much faster and easier to maintain than going through all your code and applying .toUpperCase() to your header strings. Additionally, it's not uncommon to only want the first letter of a word to be capitalized. JavaScript doesn't have a capitalize method, but you could write something like this: function capitalize(string) { const firstLetter = string.charAt(0).toUpperCase() const restOfString = string.slice(1).toLowerCase(); return firstLetter + restOfString; } capitalize('alligator'); // "Alligator" Though there may be reasons to write something like this, it can be easy to get caught up in formatting everything in your JavaScript code. Remember that CSS has you covered if you're just trying to improve the look for site visitors!

    Browser Support

    text-transform is luckily one of those CSS properties you don't have to worry about using regardless of how many browser versions you support. It's supported by all modern browsers, including IE6+.

    CSS will-change Property: When and When Not to Use It

    Paul Ryan The will-change CSS property is commonly misunderstood or not used correctly, in this short post I will demystify the property so you can make your CSS animations and transitions as performant as possible.

    What is will-change?

    In a nutshell, the will-change property is a way to tell the browser ahead of a time which properties and elements are likely to be manipulated. Using this information, the browser can make optimizations before they are needed which can result in a smoother experience. An example of this would be if we were applying a transform on an element we could inform the browser of this like so: will-change: transform; You can also declare multiple values like so: will-change: transform, opacity;

    will-change Values

    will-change can take four possible values:
  • auto - browser will apply the optimizations
  • scroll-position - indicates that the author expects to animate or change the scroll position of the element in the near future
  • contents - indicates that the author expects to animate or change something about the element's contents in the near future.
  • custom-indent - indicates that the author expects to animate or change the property with the given name on the element in the near future.
  • The value we're going to focus on is custom-indent i.e. transform, opacity, etc.

    When to use will-change?

    As stated by Mozilla's MDN, will-change should be used as a last resort. If we abuse the usage of will-change, we will suffer performance hits which is the exact opposite of what we want. If your animations/transitions are smooth and crisp then there is no need to use will-change. The browser is already making optimizations without the use of will-change.

    Don't do this!

    A common mistake people make when using will-change is this: .my-element:hover { will-change: opacity; transition: opacity .25s ease-in-out; } This is doing more harm than good, will-change is future tense so it shouldn't be applied when the animation is happening. A better use of will-change here would be to put the will-change on the parent of my-element like so: .parent-element:hover { will-change: opacity; } .my-element:hover { transition: opacity .25s ease-in-out; } This lets the browser know ahead of time to optimize for this change. Remember to use this as a last resort if your animations are janky or flickering.

    Removing will-change

    It is recommended by Mozilla to remove will-change after the element is done changing. This is why it's also recommended to set will-change via JavaScript so you can remove it. If will-change is set in the CSS stylesheet, it can not be removed. Code-wise this is quite simple and looks like this: const el = document.querySelector('.parent-element') el.addEventListener('mouseenter', addWillChange) el.addEventListener('animationend', removeChange) const addWillChange = () => { this.style.willChange = 'opacity' } const removeChange = () => { this.style.willChange = 'auto' } The code above is very simple, we're adding our will-change to the parent-element when it is hovered then when the animationend event is fired we then remove our will-change. Setting will-change in a stylesheet can make sense in some circumstances. A circumstance such as this would be an element that is likely to be interacted with multiple times, this could be something like a ripple effect on a button or a sidebar sliding out. Generally, there should only be a handful of will-change properties in a stylesheet, the rest should ideally be set through JavaScript.

    Conclusion

    This was a short little introduction to will-change, and if you're looking to dive deeper I would really recommend checking out Sara Soueidan's great article on the topic.

    Using Google Fonts in Your Web Pages

    Cooper Makhijani Google Fonts is a service provided for free by Google that allows access to thousands of fonts. All the available fonts are under Open Source licenses, meaning they're free to use for both commercial and non-commercial projects.

    Getting started

    This article will go over using Google Fonts on a webpage. Below is what a boilerplate web page looks like right now: And here's the boilerplate HTML markup: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>My web page</title> </head> <body> <h1>Welcome to my website</h1> </body> </html> Pretty boring, huh? Let's spice it up a little with a better font.

    Choosing your fonts

    It's now time for us to choose our fonts. Head on over to fonts.google.com and select a font you like by pressing the little (+) (plus) button. I'm going to use Karla. Once you've picked out your font, expand the drawer on the bottom of the page. There are two ways to import the font for use. For the first method, copy the code in the code box under the Standard label. Now head on over back to your markup and add a the copied code and a style tag to the head of the document like this. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>My web page</title> <link href="https://fonts.googleapis.com/css?family=Karla&display=swap" rel="stylesheet"> </head> <body> <h1>Welcome to my website</h1> </body> </html> You'll notice from the URL example above that Google Fonts now supports the font-display property! If you already have a separate CSS stylesheet, copy the code under the @import label and add it to the top of your stylesheet like so. @import url('https://fonts.googleapis.com/css?family=Karla&display=swap'); .element { /* ... */ }

    Using the Fonts

    We've imported our fonts, now it's time to use them. Let's set the body of our HTML markup to use Karla, like so: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>My web page</title> <link href="https://fonts.googleapis.com/css?family=Karla&display=swap" rel="stylesheet"> <style> body { font-family: 'Karla', sans-serif; } </style> </head> <body> <h1>Welcome to my website</h1> </body> </html> Now, if we take a look at our web page, it looks like this: That looks a lot better! That was easy, wasn't it? Now you can make your web pages look prettier with the free font hosting offered by Google Fonts! Thanks for reading!

    A CSS-Only Click Handler Using the :target Pseudo-Class (No JavaScript)

    Jess Mitchell There's often a point when you're building a website, especially a simple landing page, when you realize you're going to have to introduce some JavaScript. CSS, however, can often do a lot more than we give it credit for. Here we'll look at creating click handlers with only CSS! Let's say we're building an HTML and CSS landing page and we decide we want a “See more!” button to display a section of text. As soon as we think of a click event, usually it leads us to one word: JavaScript. As web developers, most of us spend a lot of time with JavaScript– and that's great! However, there are tons of things we can do with just CSS that we may not even know about!

    The CSS Pseudo-Class :target

    There are lots pseudo-classes in CSS that can help us style elements in different states. For example, you can style a button when it's hovered, active, focused, etc. One pseudo-class you might not have heard about, though, is the :target pseudo-class. The :target pseudo-class is used to select an element when that element's ID matches part of the current URL.

    When Would an Element's ID Match a URL?

    A common use case for having an element's ID show up in the URL is if you're using an anchor tag (<a>) to jump to a specific spot on the current page. For example, if it's your personal website, you might have a “Contact” button at the top of the page. On click, it could bring the user to the footer to see all your contact information.

    Using an Anchor Tag to Jump Positions on the Page

    If you've used an <a> tag before, you're likely familiar with the href attribute. If you're trying to link to a website, like Alligator.io for example, you'd create the link in your HTML like this: <a href='https://alligator.io'> Click me! </a> However, if you want your user to stay on the current page and jump down to the footer, for example, all you have to do is set an ID on the footer and use that ID for the href value in the <a> tag. <a href='#footer'> Go to the footer! </a> When the user clicks on this footer link, the page will jump to the footer and their current URL will get updated to look like: https://www.imawebsite.com/#footer The footer element's ID is now part of the current URL. In other words, it's the target!

    Creating Click Handlers with :target

    Now that we know how to create a target with HTML, how do we use that target to create a click handler without any JavaScript? Thankfully, it takes just a little CSS! Using our “See more!” button example from above, let's start by creating a link to see more text: <a href='#seeMore'> See more! </a> Our section of text we want to see doesn't exist yet, so let's create that too. <a href='#seeMore'> See more! </a> <section id='seeMore'> <p> Here's some more info that you couldn't see before. I can only be seen after you click the "See more!" button. </p> </section> When you click the “See more!” button, the URL will update to look like this: https://www.imawebsite.com/#seeMore The problem we have now is that the #seeMore section is visible to the user even though it's not supposed to be yet! Since this is all the HTML we'll need so far, let's add our CSS to manage showing the text block on click. First, let's hide the text that shouldn't show yet. <style> #seeMore { display: none; } </style> Now the text in the #seeMore section doesn't show on load or when you click the “See more!” button. This is where the :target styling comes in. Let's use the :target pseudo-class to update the styling when the “See more!” button gets clicked. <style> #seeMore { display: none; } #seeMore:target { display: block; } </style> It is literally as simple as that! On load, our text section will not show. As soon as you click the “See more!” button, it will add #seeMore to the URL and the #seeMore section becomes the target. Once #seeMore becomes the target, it will have its :target styling applied, which displays the text.

    Using :target to Toggle the Display

    If an element wasn't visible to begin with, you will probably want the option to hide it again. Luckily, we can do that with just one more line of HTML (no CSS!) Using the same example as above, let's expand the HTML to include a “Hide text” button. <a href='#seeMore'>See more!</a> <section id='seeMore'> <p> Here's some more info that you couldn't see before. I can only be seen after you click the "See more!" button. </p> <a href='#'>Hide text</a> </section> Notice that there's a new <a> tag in the text section. Since it's in the element that only shows when the user clicks “See more!”, the “Hide text” button will only show if the hidden text becomes visible. That is, the user doesn't need to see the button to hide text unless there's text to hide. The href value on the “Hide text” button is “#”. This is because we want to update the URL to no longer include #seeMore. When the “Hide text” button is clicked, it will update the URL to look like this: https://www.imawebsite.com/# With the URL updated, #seeMore is no longer the target, and the #seeMore:target styling no longer gets applied. The block of text (including the “Hide text” button) will, therefore, go back to having the display: none; styling applied. In short, update the URL and the text that was originally not displayed goes back to not being displayed. We officially have a way to toggle the text!

    Examples of When to Use :target

    If you're not sure when you would actually use the :target pseudo-class, here are some examples of how you could:
  • Click a hamburger icon to show your site's navigation menu. Include an icon to close the navigation.
  • Click an icon to display a modal. (Note: Make sure your modals are accessible if you're going to use them! )
  • Update the styling of the currently selected tab in your navigation bar when it gets clicked.
  • Browser Support

    The browser support for the :target pseudo-class is fantastic and you basically don't need to worry about it unless you're supporting IE8. As always, though, check Can I Use to be sure.

    Improve Responsiveness with flex-wrap in CSS

    Jess Mitchell The flex-wrap property is a quick way to make parent elements more responsive on various screen sizes. As with flexbox in general, it simplifies page layouts so you don't have to manually set breakpoints or manage the page overflow yourself.

    Flexbox and Managing Element Wrapping

    flex-wrap is a property specific to the flexbox (or “flexible box”) module in CSS. Flexbox is a CSS layout model that manages how child elements are displayed in a parent element. This means flexbox can be useful for general page layout (like header, nav, footer, etc). More importantly, though, it can be applied to any element on the page that has child elements. div.parent { display: flex; } Making an element a flex container is as simple as adding display: flex; to its CSS declarations. Once there's a flex container, flex-wrap can be declared on that same parent element to determine how to handle child elements that do not fit on one line by default. div.parent { display: flex; flex-wrap: wrap; } Flex wrap example The parent element must be made a flex container before flex-wrap can be applied. The flex-wrap property gets applied to the flex container only (not the child elements).

    Default Setting for flex-wrap

    By default, a flex container will try to fit its child elements on one line. This is also known as nowrap for the flex-wrap property. For this example, let's first start with a non-flex container where the children–block elements– will each be on a new line: gator cayman crocodile eggs If we make the parent element a flex container, the children will all go on one line. .flex-container { display: flex; flex-wrap: nowrap; } gator cayman crocodile eggs The default flex-wrap setting for flex containers is "no-wrap". That means you don't need to explicitly declare it like we did above. Now we have our child elements on one line but, even if your window doesn't have enough room for them, the child elements will stay on one line. As the window size changes, the child elements will continue to squish together until they eventually overflow the parent element. So, how do we fix this? flex-wrap to the rescue!

    Get to Know Your flex-wrap Options

    There are three valid values for the flex-wrap property:
  • nowrap: This is the default value for flex containers, so it does not need to be explicitly declared unless you're overriding other styles. Child elements will always stay on one line.
  • wrap: Using wrap will allow your child elements to wrap to additional lines when they no longer fit on the initial line. The element(s) that don't fit will wrap to the bottom-left in the parent element.
  • wrap-reverse: This will cause the opposite effect of wrap. Instead of wrapping the overflowing element(s) to the bottom-left, it will wrap to a new line above the first child elements at the top-left of the parent.
  • To see the difference between wrap and wrap-reverse, compare the following two examples by resizing your window: .flex-container { display: flex; flex-wrap: wrap; } gator cayman crocodile eggs This first example has overflowing elements going to a new line below the first child elements. .flex-container { display: flex; flex-wrap: wrap-reverse; } gator cayman crocodile eggs This second example does the opposite and wraps the overflowing elements above the first child elements. wrap-reverse is less common to use but it's still good to have in your CSS toolkit.

    Flexbox Shorthand: flex-flow

    If you're someone who prefers to write your code on as few lines as possible, you'll be happy to know flex-wrap is one part of the flexbox shorthand flex-flow. flex-flow is a flexbox property that replaces flex-wrap and flex-direction.

    Quick Intro to flex-direction

    flex-direction determines if your child elements should be in a row or column. The four options are: row, column, column-reverse, and row-reverse. The default value for flex-direction is row.

    Using flex-flow

    flex-flow declares the flex-direction of the parent element first and the flex-wrap value second. It should only be used if you need to explicitly declare the flex-direction and flex-wrap to differ from the default values. This means you can write these flex properties either like this: .backwards-flex-container { flex-direction: row-reverse; flex-wrap: wrap-reverse; } Or with the flex-flow shorthand to get the same effect: .backwards-flex-container { flex-flow: row-reverse wrap-reverse; } gator cayman crocodile eggs This “backwards” example will have the child elements in a row but in the reversed order (the flex-direction). It will also have the overflowing children wrap to a new row above the first row. flex-flow is the only flexbox shorthand that specifically includes flex-wrap but there are many other ones. If you prefer shorthand, most flexbox properties have shorthand options!

    Browser Support

    In general, flexbox and flex-wrap are very well-supported in all modern browsers. Even Internet Explorer (IE) has partial support for flexbox and flex-wrap after IE9.

    Flexbox Prefixes

    Using prefixes for flexbox and flex-wrap is less common these days and whether you use them will depend on which versions of browsers you're trying to support. .parent { display: flex; display: -webkit-flex; /* old versions of Chrome/Safari/Opera */ display: -ms-flexbox; /* IE10 */ flex-wrap: wrap; -webkit-flex-wrap: wrap; /* old versions of Chrome/Safari/Opera */ } Note that flex-wrap is one property of flexbox that is specifically not supported by some old versions of browsers, like Firefox. To be sure if prefixes are needed, check Can I Use for the most current information on browser support, especially if you're supporting old versions of browsers.

    CSS Basics: Using :hover and :active Pseudo-Classes

    Jess Mitchell CSS offers several pseudo-classes for styling elements that can help differentiate between various element states. Here we'll focus on :hover and :active to see how to improve visual feedback for users and make sure your UI looks great across devices!

    What is a “Pseudo-Class”?

    A pseudo-class selects the state of a selector in CSS. Pseudo-classes must be used in conjunction with a regular CSS selector, whether that be an element, class, or id. Pseudo-classes are typically based on user interactions with elements. They offer the option to change an element's styling depending on which state it's in. Hovering over an element, like a button, is one example of changing an element's state in CSS. The “hover” state can be styled differently than the default non-hovered state. Similarly, clicking a link will update a link's state in CSS and make it “active”.

    Giving Users Visual Feedback

    Using pseudo-classes can be extremely helpful for giving users immediate visual feedback. An intuitive user interface (UI) will let the user know how to interact with the UI, like whether text can be clicked. For example, updating a navigation bar item's styling on hover lets the user know the mouse is in a clickable area, which may extend past the actual text. However, if everything on a page were to have hover styling, it would visually be pretty overwhelming. It also would not tell the user much about how they should interact with the page. Therefore, it's best to ask yourself what the pseudo-class styling is supposed to tell the user. Using pseudo-classes in CSS can help give users visual feedback so they understand how to interact with the UI.

    The :hover Pseudo-Class

    The :hover pseudo-class is one of the most common ones you'll come across in CSS. Let's first look at some examples of how to use it. As a baseline, let's style all <a> tags to be the color green. a { color: green; } If we want to change the color on hover, we declare a second style where we select the <a> tags again but then add the :hover pseudo-class. a { color: green; } a:hover { color: yellow; } Try hovering here to see the intended effect. Even though :hover is commonly used for links, like in the example above, you can use it on any selector. Here are a few more examples using a <p> tag, a class, an id, and a combination of them: p:hover { background-color: green; } .gator:hover { font-weight: bold; } #cayman:hover { font-size: 2rem; } input.gator[type="text"]:hover { border: 1px solid yellow; } input.gator[type="text"]:hover span { border: 2px solid black; } Note that the pseudo-class comes at the end of a selector. It should be added to the element being hovered, which can be a parent of a more specific selector. The benefit of using the :hover pseudo-class is that CSS does all the work for us. Sorry JavaScript, but we don't need any 'if' statements or state management here!

    Using :hover with Different Devices

    When styling responsive pages, it's important to consider how those styles apply to various devices. A user may look at a webpage on a computer or phone, for example, and they may use a touch screen, mouse, or keyboard (etc) to trigger UI interactions.
  • Mouse: The :hover styling will show when using a mouse and hovering the pointer over a styled element.
  • Keyboard: Navigating by keyboard through a page will not trigger the :hover styling because there's no pointer event.
  • Phones/touch screens: The :hover and :focus pseudo-classes often get conflated, so :hover will get triggered on “click”/touch even though there's no pointer to hover.

  • The :active Pseudo-Class

    Like the :hover pseudo-class, :active should be used in conjunction with your regular CSS selectors. :active can be used to select an element in its “activated” state. Most commonly, it is used for links and refers to when a link is being selected (or clicked). To see the active styling, try clicking down on the link below: I turn purple on click This is achieved by adding the :active pseudo-class to a valid CSS selector. a { color: green; } a:hover { color: yellow; } a:active { color: purple; }

    Using :active on Different Devices

    Since :active refers to when an element is in the process of being selected, it works fairly similarly across devices.
  • Mouse/touch screens: With a mouse or touch screen, the active styling will show when an element is selected (before the selection is released).
  • Keyboard: When using a keyboard, the active styling will not show if you select an element with the Enter key because it's submitted on keydown. However, if you select an element (like a button) with the space bar, it should show the active styling until you release it.

  • Does the Order of Pseudo-Classes Matter?

    In the case of pseudo-classes, the order does matter. :hover styling will override :active styling, so it must be declared before the :active styling. Correct Order Using the order of pseudo-class declarations in the example above, we get the intended styling here for the default, hovered, and active states. However, if we reverse the :hover and :active styling declarations, the :hover styling will unfortunately override the :active styling. a { color: green; } a:active { color: purple; } a:hover { color: yellow; } Wrong Order Notice that now when you click down on the link, it doesn't turn purple anymore, even though we've declared the active state color. Always place your active styles after your hover styles to make sure they get displayed correctly.

    Recap

    When styling element states with :hover and :active, remember to:
  • Use these pseudo-classes to convey information about elements (like if they're clickable)
  • Put the pseudo-class at the end of the CSS selector
  • Be mindful of how pseudo-classes show up on different devices
  • Make sure :active comes after :hover in your CSS declarations
  • Introduction to Tailwind CSS

    Joshua Hall In this article we'll be looking into my personal favorite design framework: Tailwind CSS. A completely style-agnostic, utility-based library for creating quick and responsive designs. Tailwind is so simple that once you understand the naming conventions and patterns you can almost guess most of the functionality without needing the documentation. All of the options introduced here can be explored in more detail in the official docs.

    Installation

    While there are a few different methods for setting up Tailwind, like Gulp, postCSS, or even their own CLI, the simplest route for getting started for learning's sake is just be to use the CDN URL from unpkg: https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css. Or, you can install the library into your project using npm or Yarn: $ npm i tailwindcss # or, if Yarn is more your thing: $ yarn add tailwindcss

    Boilerplate

    Here's a simple boilerplate HTML file that includes Tailwind from unpkg: index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <link rel="stylesheet" href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css"> <title>Tailwind CSS</title> </head> <body> </body> </html>

    Colors

    The class naming for colors is always the same, element-color-intensity. So a red background becomes bg-red-500, with the number value ranging from 100 to 900. This patterns applies to borders, backgrounds, and text. Here's a simple example: <h1 class="text-blue-400">Hello World</h1> <p class="text-white bg-indigo-900">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Neque, veniam.</p> <!-- Border needs to be set before the border-color can be changed --> <input type="text" class="bg-transparent text-white border border-red-600" placeholder="input...">

    Size and Spacing

    Width and height, shortened to w and h, can take values from 0 to 64 (with some values missing, which you can check for in the docs or VSCode's IntelliSense) and a few key words like auto, full for 100%, or screen for 100vw/vh. Width can also use fractions out of 1-6 or out of 12, so we could write 50% like 1/2, 2/4, 3/6, or 6/12. Spacing works very similarly, just the property, side (shorthand without the dash), then the value. So padding-bottom: 2rem; becomes pb-8, again ranging from 0 to 64 and the side being eiter t,b, l, r, x for right and left, or y for top and bottom. <div class="bg-green-700 h-16 w-auto mr-10"></div> <div class="bg-blue-700 h-24 w-4/6 my-16"></div> <div class="bg-red-700 h-40 w-6/12 mx-auto"></div> <div class="bg-purple-700 h-56 w-2/12 ml-48"></div> <div class="border border-white h-40 w-56 mt-10 mx-auto"> <h1 class="text-white py-16 px-16">I'm a box</h1> </div>

    Layout

    Tailwind offers us many of the comforts of standard CSS positioning, like floats, position, and even Flexbox. Using them is almost exactly as you would expect, except that with Flexbox you just need to initialize it with flex first. Similar to size, the naming pattern is just property-value, so a right float becomes float-right and justify-content: center; becomes justify-center. <!-- Basic Navbar --> <nav class="flex justify-between items-center px-16 bg-purple-800 text-white h-24"> <h1>Title</h1> <ul class="flex justify-between w-56"> <a href="#"> <li>Link</li> </a> <a href="#"> <li>Link</li> </a> <a href="#"> <li>Link</li> </a> </ul> </nav>

    Typography

    Besides the standard things we can already do in CSS, Tailwind offers some shortcuts for what would otherwise be very tedious, like adding contingency for our font-family, which we can take care of with just font-sans, font-serif, or font-mono and have a group of fonts taken care of. Instead of the 0-64 units we've been using, font-size (shortened to text) takes xs,sm,base,lx, and xl through 6xl. Besides those exceptions, most of the text options is CSS are available with the same naming patterns as before. <p class="text-md font-mono font-bold text-white">Hello World</p> <p class="text-lg font-sans line-through text-white">Hello World</p> <p class="text-4xl font-serif text-center text-white">Hello World</p> <p class="text-6xl font-mono text-right italic font-extrabold text-white">Hello World</p>

    Responsiveness

    This is where Tailwind really shines, in cutting down on the need for media queries. With these prefixes, we can limit a class to only work above a specific width, with the un-prefixed version, like what we've been working with so far, working for everything outside of our range.
  • sm 640px
  • md 768px
  • lg 1024px
  • xl 1280px
  • <body class="bg-gray-900 flex flex-col md:flex-row"> <div class="h-32 w-32 mt-16 mx-auto lg:bg-orange-500 md:bg-red-500 sm:bg-purple-800 bg-white"></div> <div class="h-32 w-32 mt-16 mx-auto lg:bg-orange-500 md:bg-green-800 sm:bg-indigo-300 bg-white"></div> <div class="h-32 w-32 mt-16 mx-auto lg:bg-orange-500 md:bg-blue-200 sm:bg-teal-600 bg-white"></div> </body>

    Conclusion

    Hopefully this was an helpful introduction to this powerful little library. The learning curve for Tailwind is so small and its syntax so consistent that with very little experience you can start creating wonderful designs before even needing to look at the CSS.

    CSS Units Explained

    Jess Mitchell CSS has several options for which units to use when determining the size of various CSS properties. Learning all your options for CSS units can be key for styling in a way that's easy to manage and looks great on any screen.

    What is a CSS Unit?

    A CSS unit determines the size of a property you're setting for an element or its content. For example, if you wanted to set the property margin of a paragraph, you would give it a specific value. This value includes the CSS unit. Let's look at a small example: p { margin: 20px; } In this case, margin is the property, 20px; is the value, and px (or “pixel”) is the CSS unit. Even though it's common to see units like px used, the big question is often, “What's the best unit to use here?” Well, let's find out!

    Absolute vs. Relative Units

    When considering all the options for which units to use, it's important to consider the two categories of units: absolute and relative.

    Absolute Units

    Units that are “absolute” are the same size regardless of the parent element or window size. This means a property set with a value that has an absolute unit will be that size when looked at on a phone or on a large monitor (and everything in between!) Absolute units can be useful when working on a project where responsiveness is not being considered. For example, desktop apps that can't be resized can be styled for the default dimensions. If the window doesn't scale, you don't need the content to either. Hint: Absolute units can be less favourable for responsive sites because they don't scale when the screen size changes.
    Absolute Unit Description Example
    px 1/96 of 1 inch (96px = 1 inch) font-size: 12px;
    pt 1/72 of 1 inch (72pt = 1 inch) font-size: 12pt;
    pc 12pt = 1pc font-size: 1.2pc;
    cm centimeter font-size: 0.6cm;
    mm millimeter (10 mm = 1 cm) font-size: 4mm;
    in inches font-size: 0.2in;
    Pixels (px) are typically the most popular absolute unit for screens. Centimeters, millimeters, and inches are more common for print and you may not have even known they were options!

    Relative Units

    Relative units are useful for styling responsive sites because they scale relative to the parent or window size (depending on the unit). As a general rule, relative units can be used as the default for responsive sites. This can help you avoid having to update styles for different screen sizes. Relative units can be a little more difficult than absolute units in determining which to use, so let's go through your options in detail.
    Relative Unit Description
    % Relative to the parent element's value for that property
    em Relative to the current font-size of the element
    rem Relative to the font-size of the root (e.g. the <html> element). “rem” = “root em”
    ch Number of characters (1 character is equal to the width of the current font's 0/zero)
    vh Relative to the height of the viewport (window or app size). 1vh = 1/100 of the viewport's height
    vw Relative to the width of viewport. 1vw = 1/100 of the viewport's width.
    vmin Relative to viewport's smaller dimension (e.g. for portrait orientation, the width is smaller than the height so it's relative to the width). 1vmin = 1/100 of viewport's smaller dimension.
    vmax Relative to viewport's larger dimension (e.g. height for portrait orientation). 1vmax = 1/100 of viewport's larger dimension.
    ex Relative to height of the current font's lowercase “x”.
    It's not always clear which of these options is best to use for each type of CSS property. For example, % is usually more appropriate for layout-related properties like width than it would be for font-size. Here are some examples of when you would use each relative unit. (Spoiler: it's almost never ex. )
  • %: You want a child element to have 10% of the parent's width as a margin so it never fills the whole parent element. If the parent's size changes, the margin will update too..child { margin: 10%; }
  • em: You want the font of a child element to be half the size of its parent's font-size (e.g. the paragraph under a section's title)..child { font-size: 0.5em; }
  • rem: The font-size should be twice the size as the root element's font. This could be how you size your headers because they should all be the same size regardless of the parent container..header { font-size: 2rem; }
  • ch: You have a mono-spaced font (the characters are always the same width) and you only have space for 10 characters..small-text { width: 10ch; }
  • vh: Your landing page should always be the height of the viewport/window..wrapper { height: 100vh; }
  • vw: You have a section with text that should be half as wide as the viewport/window..half-size { width: 50vw; }
  • vmin: You have an image that should always be as wide as the viewport's smaller dimension. On a phone being held in portrait mode, the image will be as wide as the viewport's width..min-width { width: 100vmin; }
  • vmax: You don't care if an image gets cut off because you want it to completely fill the larger dimension of the viewport. For example, if an image of a pattern is used as a background..max-width { width: 100vmax; }
  • ex: You probably won't come across ex very often but it's generally a good measure of a font's mid-section. Let's say you want to a font's line-height to be double the height of the font's “x”..double-x { line-height: 2ex; }

  • Overall, when and how you choose your CSS units will come down to a couple questions:
  • Do I want what I'm styling to scale when the viewport size changes?
  • If I do want it to scale, what do I want it to scale relative to in the app?
  • Once you've answered these questions, it's a lot easier to nail down which unit to use.

    Further Reading

    You can dig deeper into viewport units by reading this article, or have a look at this article about em vs rem units if the difference between those two units is still somewhat unclear.

    Back to Basics: CSS Transitions for Simple Animations

    William Le CSS isn't just for creating static web designs. You can create simple dynamic animations using CSS transitions. Things can move! Jump! Change colors! In this article, you'll learn the basics so that you can get started using CSS transition animations in your websites. CSS transition is aptly named: it helps transition from an initial visual state to another visual state. That's somewhat theoretical language, so let's think about it using a metaphor.

    Visual State

    Imagine there's a soccer ball at your feet. It's initially 0 ft from your feet. When you kick it, the next state is 100 ft away from you. How would we recreate this scenario in HTML/CSS? Let's tackle it! index.html <div class="soccerball" /> style.css .soccerball { width: 50px; height: 50px; border-radius: 100%; background-color: #dddddd; transform: translateX(0px); /* initial state */ } .soccerball:active { transform: translateX(100px); /* next state when active/clicked */ } Clicking on the ball moves it 100px to the right… Hmmm… not quite right. The soccer ball just *zapped* over there. Let's add the transition rule! style.css .soccerball { width: 50px; height: 50px; border-radius: 100%; background-color: #dddddd; transform: translateX(0px); transition: transform 250ms linear; /* */ } .soccerball:active { transform: translateX(100px); } Let's breakdown the parts in a transition definition: CSS transition syntax anatomy
  • CSS property can be anything! It can be width, background-color, display, etc. It specifies which property the transition should apply to. You can also use the keyword all to target all the properties on the element.
  • Duration is the amount of time it needs to animate. The ms here means milliseconds. You can also use 0.25s to denote seconds.
  • Timing function is the speed of the change. It's not quite the same as duration. To learn about timing-functions, see this in-depth guide from MDN. The available keywords are ease, ease-in, ease-out, ease-in-out, linear, step-start and step-end. You can also define your own timing functions using cubic-bezier.
  • All in all, this transition definition means div.soccerball will take 250 milliseconds to move 100px along the X-axis. Try clicking on the ball! That's better! This is the brilliance of CSS transition! You simply give it two visual states, and it knows how to fill-in-the-blanks. In technical terms it can be said that transition knows how to interpolate intermediate values between two fixed values (0px and 100px). CSS transition is one of those suprisingly intelligent aspects of CSS that makes me feel blessed to have such a simple/powerful tool!

    Transitioning Multiple CSS Properties

    With transition you can even define multiple properties by separating each property with a comma: .soccerball { width: 50px; height: 50px; border-radius: 100%; background-color: #dddddd; transform: translateX(0px) scale(1); transition: transform 250ms linear, background-color 500ms linear; /* comma! */ } .soccerball:active { background-color: white; transform: translateX(100px) scale(2); } Now, clicking div.soccerball animates several of its CSS properties. And, as you can see, even colors can be transitionned from one to another: CSS transitions have been around since 2012 so browser support is solid!

    Conclusion

    The Web is a much more captivating place with animations! Try using CSS transition and you'll find that they can really boost the overall user experience of your website. Once you're comfortable with the concepts and usage of transitions in CSS, you can then move on and learn about animations using the @keyframes at-rule. View documentation for the CSS transition property on MDN

    Practical Guide to Using CSS Position Relative & Absolute

    William Le In this article, you'll learn how to use CSS position: relative and position: absolute through ample amounts of demos, and learning aids. CSS position is sometimes considered an advanced topic because it can do things that are somewhat unexpected. Well, don't let “the experts” intimidate you from pursuing excellence in your CSS competence! It's a very accessible topic once you're equipped with some of the underlying ideas.

    Render Flow

    An important concept to understanding relative/absolute positioning is render flow. The general idea is that HTML elements all take up some space. Your browser's rendering engine always renders everything in a grid-like fashion, starting at the top-left corner and moving successively towards the bottom-right until it's done placing all of your HTML content. If you've ever had a slow internet connection, and watched as large stuff on the webpage would push everything rightward and downward, that is essentially “render flow” in action. You can change this default behavior using CSS position.

    CSS Position

    CSS position is sometimes considered an advanced skill because it's not as intuitive as font-size or margin, etc., since it changes the natural “render flow” of the browser. These are the possible values for CSS position: .foo { position: static; /* position: relative; position: absolute; position: sticky; position: fixed; */ } Today we're just going to look at position: absolute and position: relative since they're perhaps the most versatile ones that will get you a lot of mileage once you feel confident with them.

    Relative Positioning

    When you make an HTML element position: relative, it'll remain “in the flow” of the layout but you can move it around! .green-square { position: relative; top: 25px; left: 25px; /* ... */ } Along with position: relative you'll usually want to define the top, right, bottom, or left offset. You can think of “relative” position as being: “relative to where it was initially positioned.” In this case, the green square is now 25px from the left, and 25px from the top of where it was initially going to be. What's also worth noting is that its width and height is preserved in the square grid. That means it's still considered “in the flow” of the layout… it just got kinda nudged.

    Absolute Positioning

    Absolute positioning is a very powerful CSS rule for moving HTML elements around. Sometimes yielding unexpected results: .orange-square { position: absolute; top: 0px; left: 0px; /* ... */ } The orange square is actually the 13th of these 25 squares (the one in the middle of the grid), but it looks like it's the last square! Weird. Using position: absolute takes elements “out of flow” so its grid space gets collapsed. Yea but why's it all the way up there?!

    Originating coordinates

    The orange square gets placed at the 0x, 0y coordinates (eg.: the top-left corner). Just how browser rendering always begins at the top-left corner, position: absolute elements use that as their rendering origin too. You can use top/right/bottom/left properties to offset it from there. But, you can also give it different originating coordinates… .grid { position: relative; } .orange-square { position: absolute; top: 0px; left: 0px; /* ... */ } In the example above, the parent element (div.grid) has the position: relative rule which causes the orange square to take that as its rendering origin. Pretty weird if you haven't witnessed this before. I didn't even learn this until 2 years ago… after having used CSS for about 6 years! While this may seem unintuitive behavior, it's actually intentional! Allowing for this gives you a lot of control over where/how you arrange HTML elements… as we'll see in the demos below.

    Demo Time!

    Here's some examples of using position: absolute and position: relative to create some interesting designs.

    Alice in Wonderland

    This is an excerpt from “Alice in Wonderland” where some of the letters are nudged down using a few position: relative rules. <p> The rabbit-hole went straight on like a tunnel for some way, and then dipped suddenly <span style="position: relative; top: 4px">down</span> <span style="position: relative; top: 8px">.</span> <span style="position: relative; top: 12px">.</span> <span style="position: relative; top: 16px">.</span> </p> Inline elements are moved in this demo, but you can do this to block elements too! Rest assured: other HTML elements won't take up its space, and thus ruining this effect.

    Overlapping HTML elements

    As we covered earlier, if you place absolutely positioned elements inside relatively positioned ones you're able to effectively group them into layers of HTML elements. Wrapping both of these absolutely positioned images with a parent <div> that's relatively positioned, we get this schnazzy portrait of our favorite alligator. Once you get comfortable using position: relative and position: absolute together, you'll begin to think in terms of creating lush layers of HTML elements instead of thinking in a strictly 2D mindset. It's something that will take your CSS game to the next level.

    Color pit

    This demo is similar to the previous one, but we're using 5 images here that are absolutely positioned inside a single relatively positioned container <div>. What's cool is that once you get the width and top/left values just right for each of the 5 images, you can essentially treat this thing as a single visual element. Move it around the webpage, put other HTML elements next to it, animate it… it'll retain this exact look as though it's a single image.

    Conclusion

    When you start using position: relative and position: absolute it opens a new world of design possibilities. You can create layered visual elements, and feel a deep sense of confidence about how browsers will render, and thus place the visual elements that you've so meticulously designed. Learn more about CSS position at the Mozilla Developer Network

    Understanding CSS Float

    William Le In this article, learn how to use CSS float positioning, as well as some of the pitfalls when using it. Newbies to CSS usually have a difficult time grasping how float positioning works. This is probably because people tend to overuse it, or many times they're using a CSS framework that uses it waaaay too much (lookin' at you Bootstrap v2 ). Using float too often can make page layouts unpredictable and prone to breaking. After teaching a bunch of people how to use float, I've come up with 3 rules/guidelines to easily understand float.

    The 3 Rules

  • Rule #1 Use float for its intended purpose
  • Rule #2 Parents containing float elements will collapse
  • Rule #3 Use clear in conjunction with float
  • Rule #1: Use Float for its Intended Purpose

    Web design was deeply inspired by print design disciplines, and float is an homage to these roots when a print designer would need to “pull” a visual element to the side while allowing other content to freely flow around it. Today, this remains a design pattern for websites and, believe it or not, there aren't any CSS workarounds for accomplishing what float does. float: right <p> <img class="bitey-img" src="apex-predator.jpeg"/> The alligator is a crocodilian in the genus Alligator of the family Alligatoridae. The two living species are... </p> .bitey-img { float: right; } This was accomplished by simply using float: right;. The browser window can be resized and the text will flow naturally around the image! You can't accomplish this with Flexbox, position: absolute, or any workarounds. It's a deceptively powerful feature that only float can do! You can also use float: left; to pin something to the other side: float: left View the code on glitch.com And… that's it! These are really the only pragmatic uses for float. It's used when you want something to pin an HTML element to the side AND you want content to fill up the empty space around it. If any of these criteria are missing, you'd be better suited using another approach (like CSS Flexbox).
    Case-in-point: Old versions of Bootstrap v2, used float rules everywhere in the codebase. For example, the .row-fluid span elements: Snippet of Bootstrap code Inevitably people would customize their Bootstrap theme, and then start to see the layout breaking. It was utter chaos! Thankfully the Bootstrap team has largely removed float rules from new releases.

    Rule #2: Parents Containing Floated Elements Will Collapse

    In the illustration below, the <div> contains three other <div> elements that have float: left; applied. The parent element has a computed height of 0px because it won't expand to contain floated elements: Parent element collapses This is pretty weird if you're new to CSS. The containing <div> will only expand for non-floated elements: Parent elements expends on non-floated elements View the code on glitch.com

    Rule #3: Use Clear in Conjunction with Float

    Some CSS rules complement other CSS rules, like font-family and font-size for example. When you reach for one them, you'll usually use the other. Like two peas in a pod! The same goes for float and clear. Generally speaking, if you're going to use float you should consider using clear. Or your layout can break: The 2nd headline shouldn't be wrapping the image. Switch to the “View Source” window, and try editing clear: none to clear: both. This fixes the issue, and puts the headline on its own line. Using clear will make your floated elements predictable, and thus more enjoyable to use! clear can have a value of none (the default), right, left, both, inline-start or inline-end.

    Conclusion

    The float property has a very special role in CSS. It does something that no other CSS property can do, and if you follow these 3 Rules you'll be able to leverage float fruitfully in your designs.

    rem vs em Units in CSS

    We have many good choices when it comes to units in CSS. In today's world of responsive designs, relative units like the em or rem units give us adaptability and flexibility right out of the box that allows for sizes to be based on the font-size(s) defined higher-up in the markup. You've probably been using em and rem units now for a while already, but you might be wondering about the exact difference between the two and which unit is better suited for your use cases. Let's break it down as briefly as possible. TL;DR: em units for the font-size property will be relative to the font-size of the parent element. em units on other properties than font-size will be relative to the font-size of the current element. rem units sizes will always be relative to the font-size of the root html element.

    em Unit

    em is borrowed from the typography world, and it's a unit that allows setting the font-size of an element relative to the font-size of its parent. Let's take this simple example: .parent { font-size: 18px; } .child { font-size: 1.5em; } With that example, the child would have a font-size of 27px (1.5 * 18px = 27px). If the parent element doesn't specify a value for font-size, a value will be looked for higher up in the DOM tree. If no font-size is specified all the way up to the root element (<html>), then the browser default of 16px is used.
    Pretty simple and straight-forward right? em units can be used for much more than just setting font-size however, and they can be used pretty much everywhere units are expected (padding, margin, width, height, max-width,…you get the picture!) When em units are used on other properties than font-size, the value is relative to the element's own font-size. Let's add to our example: .parent { font-size: 18px; } .child { font-size: 1.5em; padding: 2em 1em; }
  • The padding top and bottom on .child will be 54px. That's 2 times the font-size of our current element's font size (2 * 27px)
  • The padding left and right on .child will be of 27px. That's 1 time the font-size of our element.
  • Remember: when em units are used on font-size, the size is relative to the font-size of the parent. When used on other properties, it's relative to the font-size of the element itself.

    Compounding effect: trouble in paradise danger

    So far everything is well and good with using the em unit, but a problem can come about from the fact that the unit can compound from one level to the other. Let's keep a similar basic example: .parent { font-size: 15px; } .child { font-size: 2em; } But let's use it in our markup like this: <div class="parent"> I'm 15px <div class="child"> I'm 30px, as expected <div class="child"> I'm 60px, trouble starts! <div class="child"> I'm 120px, now we're really in trouble! </div> </div> </div> </div> I'm 15px I'm 30px, as expected I'm 60px, trouble starts! I'm 120px, now we're really in trouble! So, as you can see, the effect of em units can be compounding when multiple em-font-sized elements are within one another. This can become a problem and can lead to unintended consequences in your designs. This problem is the reason why the rem unit was created.

    rem Unit

    The rem unit, short for root em is a relative unit that'll always be based upon the font-size value of the root element, which is the <html> element. And if the <html> element doesn't have a specified font-size, the browser default of 16px is used. So that means that, by using the rem unit, the values of parent elements are ignored, and only the value of the root is taken into consideration. With a similar example, but in rem: .html { font-size: 16px; } .parent { font-size: 15px; } .child-rem { font-size: 2rem; } <div class="parent"> I'm 15px <div class="child-rem"> I'm 32px, as expected <div class="child-rem"> I'm 32px, yep! <div class="child-rem"> I'm 32px, like clockwork! </div> </div> </div> </div> I'm 15px I'm 32px, as expected I'm 32px, yep! I'm 32px, like clockwork!
    As you can see, using rem units allow us to avoid the compounding effect of em units. With rem things are always and consistently based on the font-size or the root element, so there are no surprises. The same goes for other values than font-size (margin, padding,…) Using rem units on those will still be relative to the font-size of the root element.

    em vs rem, Which is Better?

    There's no better unit really, and it all depends on your personal preferences. Some people like to design everything in rem units for consistency and predictability, while others like to also use em units in places where the influence of nearby parent elements would make sense.

    Getting Started with Animate.css

    Paul Halliday Animations. They can absolutely make or break the user experience of your application. When implementing CSS animations on your own, you'll likely run into the same issues over and over again. Animate.css seeks to solve this issue by giving you access to common animations such as fadeIn, fadeOut, bounce, flash, tada, and countless others! Let's see this in action with a simple JavaScript project:

    CSS Animations

    Make a new folder with two files - index.html and app.js: $ mkdir animate-css-example $ cd animate-css-example $ touch index.html $ touch app.js Prior to using Animate.css, let's look at how we can create fadeIn and fadeOut animations using CSS3. Inside of index.html, I have the following: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>CSS Animations</title> <link rel="stylesheet" href="style.css"> </head> <body> <div> <input type="text"> <button onclick="addTodo()">Add Todo</button> </div> <ul> </ul> <script src="app.js"></script> </body> </html> Our addTodo function inside of app.js looks like this: const addTodo = () => { const ul = document.getElementsByTagName('ul')[0]; const input = document.getElementById('todoInput').value; if (input.length > 0) { const li = document.createElement('li'); li.classList.add('fadeIn'); li.appendChild(document.createTextNode(input)); ul.appendChild(li); document.getElementById('todoInput').value = ''; } }; The key aspect of this is simply the addition of the fadeIn class whenever we add a new Todo. This is a standard CSS3 animation and can be referenced as such: .fadeIn { animation: fadeIn 1s; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } Todo animation

    Enter Animate.css

    Now that we've seen how we might do this ourselves without Animate.css, let's add Animate.css to our project to handle the heavy lifting for us! Depending on your build system, you can install Animate.css in a variety of ways: # via npm: $ npm install animate.css # via yarn: $ yarn add animate.css Or we can go simpler and load this via CDN and that's what we'll be doing inside of our project: <head> <!-- ... --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css"> </head>

    Adding Animations

    To use a particular animation (such as tada, fadeIn, bounceInDown, etc) we first need to add the class animated to the element. For the sake of our example, let's add it to our body tag so that each starting element inside of the DOM is animated on start up: <body class="animated"> <!-- Omitted --> </body> Nothing happens at this point. That's because animated simply tells Animate.css that we'd like to animate this element in the future and this is responsible for set-up. Let's add the zoomIn class to the body: <body class="animated zoomIn"> <!-- Omitted --> </body> Body element with zoomIn animation Woosh! Each time we refresh the page, the content now zooms in to the page. What if we wanted this to repeat over and over again? Say… infinitely? Let's add the infinite class to the mix: <body class="animated zoomIn infinite"> <!-- Omitted --> </body> This now repeats without us having to refresh the page. Tada! Let's remove the fadeIn animation from our style.css file, and use Animate.css to apply the fadeIn instead. Challenge: Based on what you know now - how might we go about doing this? Well, it's as simple as adding animated fadeIn to the classList upon creation of a new li: const addTodo = () => { const ul = document.getElementsByTagName('ul')[0]; const input = document.getElementById('todoInput').value; if (input.length > 0) { const li = document.createElement('li'); const animations = [ 'animated', 'fadeIn' ]; li.classList.add(...animations); li.appendChild(document.createTextNode(input)); ul.appendChild(li); document.getElementById('todoInput').value = ''; } };

    Summary

    There we have it! We no longer have to maintain common CSS animations and can rely on a consistent, easy to use out of the box solution with Animate.css. To take full advantage of this inside of your own applications, take a look at the full list of animation classes here: Animation class list. You can find the source code for this article here: Source code

    Understanding the currentColor Keyword in CSS

    Now that that we have custom properties in CSS, we pretty much have full power over our own variables in CSS. But even before those become helpful, we can use a keyword available since the CSS Color Module Level 3, currentColor, to keep colors consistent within elements. currentColor acts like a variable for the current value of the color property on the element. And the Cascading part of CSS is still effective, so if there's no defined color property on an element, the cascade will determine the value of currentColor.

    Usage

    currentColor is useful when you want a certain color to be consistent in an element. For example, if you want an element to have a border color that's the same as the element's text color, using currentColor makes a lot of sense because then if you decide the main text color you can change the value at only one place.

    An Example

    Words are all well and good, but nothing beats an example! Let's make use of currentColor at a few different places in a simple example. You'll see how currentColor can also be really useful as the value for the fill properties of SVGs. Here's what our final example looks like (hover over it if you can): First, our markup: <div class="outer-circle"> <svg width="150" height="150" viewBox="0 0 322 322"> <g fill="none" fill-rule="evenodd"> <circle class="main-circle" cx="161" cy="161" r="161"/> <circle class="left-eye" fill="#6A76C0" cx="108" cy="109" r="25"/> <path d="M112 239h99a49.5 49.5 0 0 1-99 0zM161 201c13.8 0 25-26.2 25-40 0-9.2-8.3-17.5-25-25-16.7 7.5-25 15.8-25 25 0 13.8 11.2 40 25 40z" fill="#51BAB6"/> <circle fill="#6A76C0" cx="221" cy="109" r="25"/> </g> </svg> </div> As you can see, there's nothing fancy going on with the markup, just an outer div and a simple SVG graphic in it. The magic happens in the CSS styles: .outer-circle { color: gold; border: 10px solid currentColor; box-shadow: 0px 0px 15px currentColor; width: 200px; height: 200px; border-radius: 50%; margin: 2rem auto; display: flex; align-items: center; justify-content: center; } .main-circle { /* inherited from parent */ fill: currentColor; } .outer-circle:hover .left-eye { fill: currentColor; }
    What's more, the value for color can just a well be a CSS variable and currentColor will still end up with our expected value: The markup is basically the same, except for an additional class on the outer circle: <div class="outer-circle alternative"> <!-- ... --> </div> And then in the styles we override the color from .outer-circle and use the value of one of the CSS variables available on this site instead: .alternative { color: var(--code); }

    Wrapping Up

    Your mileage with currentColor may vary, because many properties that include a color will default to the current value of color anyway (border, box-shadow, text-decoration…). Add that to the fact that we now have full blown CSS variables, you may find that you don't pull currentColor from your bag of tricks very often these days. Still though, it's there if the need ever arrises. It can become especially helpful to make sure SVG icons are filled with the same color as the current text color. Browser Support Can I Use currentcolor? Data on support for the currentcolor feature across the major browsers from caniuse.com.

    Gradient Borders and Border Images in Pure CSS

    Borders in CSS are old news, but maybe you didn't know that border images and gradient borders are also possible with CSS now, thanks to two properties: border-image-source and border-image-slice.

    Border Images

    You can use images that replace the default border style. Here's a simple example. First, our markup: <div class="box box-1">Just a box! </div> And then the styles for our box: .box { width: 400px; height: 200px; max-width: 100%; background: var(--bg2); margin: 1rem auto; display: flex; align-items: center; justify-content: center; font-size: 2rem; } .box-1 { border: 20px solid; border-image-source: url(/url/to/some/fancy/image.jpg); border-image-slice: 60 30; } Just a box! You'll notice that there's still needs to be a regular border applied to the element because the border image replaces the regular border style. border-image-source specifies the source image, which can be a URL to a raster or vector-based image (SVG) or a data URI. border-image-slice is also needed in order for the desired effect to be achieved. That one can be a little complicated to fully grasp, but the gist of it is that behind the scenes the engine slices the image into a 3 X 3 grid, with the center section being transparent by default. border-image-slice is used to specify how the image is distributed on that grid. It can take up to 4 values which can be numerical or percentage values. Here's a great reference article by Codrops and another one by CSS-Tricks if you want to venture into fully understanding border-image-slice.

    Shorthand property with border-image

    There's a shorthand property to specify the values for both border-image-source and border-image-slice all at once: border-image. Here's the same example, but using the shorthand: .box-1 { border: 20px solid; border-image: url(/url/to/some/fancy/image.jpg) 60 30; }

    Gradient Borders

    Since gradients in CSS are really generated images, creating gradient borders is as simple as using a linear, radial or conic gradient in place of a regular image source. First, a linear gradient border: .box-2 { border: 10px solid; border-image-source: linear-gradient(45deg, rgb(0,143,104), rgb(250,224,66)); border-image-slice: 1; } Linear gradient! As you'll notice, the slicing on such gradients is much simpler and a simple value of 1 will do. So, using the shorthand, we get: .box-2 { border: 10px solid; border-image: linear-gradient(45deg, rgb(0,143,104), rgb(250,224,66)) 1; }
    Here's the same example, but as a radial gradient: .box-3 { border: 10px solid; border-image: radial-gradient(rgb(0,143,104), rgb(250,224,66)) 1; } Radial gradient!
    And then finally a conic gradient for good measure, here with all the hues of the color wheel to create a rainbow gradient: .box-4 { border: 10px solid; border-image: conic-gradient(red, yellow, lime, aqua, blue, magenta, red) 1; } I

    What About Border Radius?

    Unfortunately border images can't have a radius just yet, so if you want your element to have a border radius and a gradient border, you'll have to resort to using a workaround that probably involves another HTML element. Browser Support Can I Use border-image? Data on support for the border-image feature across the major browsers from caniuse.com.

    Creating a CSS Spinning Loader Animation

    Adebiyi Adedotun A slow network isn't the worst thing in the world - it put me in front of the Twitter spinning loader animation for long enough for me to think: “I could create something like this”. And that's what this post is about, creating a simple CSS spinning loader animation similar to Twitter's. Although Twitter's is made from an SVG, it can also be created out of pure CSS using a simple CSS keyframe animation, with nothing but a single HTML element. As you'll see, we'll make heavy use of CSS variables to make our resulting CSS more flexible and extensible. Let's just get to it. Note that the example in this post is not meant to be 100% identical to Twitter's loading animation.

    The Idea

    My inital thought was to:
    1. Create a circle
    2. Rotate the circle indefinitely from 0 to 360deg, and
    3. Find a way to indicate that the circle is being rotated
    In CSS pseudocode (if you will), this roughly means:
    1. Draw a square with a border radius of at least 50%
    2. Animate a circle continually from 0 to 360 degrees
    3. Indicate that the circle is indeed rotating
    The third point seemed fuzzy. But let's keep going.

    First, some initial setup

    :root { --s-loader-wrapper-bg-color: rgb(21, 22, 43); --s-loader-width: 20px; --s-loader-height: var(--s-loader-width); --s-loader-border-color-trans: rgba(29, 161, 242, 0.2); --s-loader-border-color-full: rgb(29, 161, 242); } body { margin: 0; background: var(--s-loader-wrapper-bg-color, rgb(21, 22, 43)); height: 100vh; width: 100%; display: flex; align-items: center; justify-content: center; }

    What's going on with the initial setup?

    On the :root pseudo-class, we defined some CSS variables:
    1. --s-loader-wrapper-bg-color: the background color for the loader's parent container
    2. --s-loader-width: the loader width
    3. --s-loader-height: the loader height (notice how we can assign a variable to another variable)
    4. --s-loader-border-color-trans: an opaque version of the loader border color
    5. --s-loader-border-color-full: a non-opaque version of the loader border color (this will do the trick of indicating the loader rotation)
    On the body element, we:
    1. Removed the browser default margin on the body element
    2. Applied a background color (rgb(21, 22, 43) is a fallback for --s-loader-wrapper-bg-color)
    3. We set the width and height
    4. The display, align-items and justify-content centers the children of the body (the spinning loader - in this case)
    You can read on viewport units and centering with flex or grid

    The Spinning Loader Element

    .spinning-loader { width: var(--s-loader-width); height: var(--s-loader-height); border: 5px solid var(--s-loader-border-color-trans); border-left-color: var(--s-loader-border-color-full); border-radius: 50%; background: transparent; animation-name: rotate-s-loader; animation-iteration-count: infinite; animation-duration: 1s; animation-timing-function: linear; position: relative; }

    What's going on here with the spinning loader?

    We set an equal width and height on the spinning loader so we can get a perfect square. Then we:
    1. Create a border for the 4 sides with sufficient opacity.
    2. Reduce the opacity on all border sides except for one of them (the left one in this case). That'll serve as a spinning-indicator. The different color on only one of the border sides is the secret sauce here.
    3. Create a perfect circle by applying a border-radius of 50% to the square.
    4. Make the background of the div transparent.
    5. animation-name - a reference to the animation name (we'll define that next).
    6. animation-iteration-count: how many cycles should the animation go?
    7. animation-duration: how long should each cycle take?
    8. animation-timing-function: this defines the speed of an animation over time. Here a timing function of linear works for our needs because the speed will be constant.

    Next we define the actual animation using the @keyframes at-rule - applying a rotation transformation from 0 to 360 degrees: @keyframes rotate-s-loader { from { transform: rotate(0); } to { transform: rotate(360deg); } } We rotate the loader infinitely from 0deg to 360deg. You can omit the deg in 0deg. Pretty much any unit in CSS can be omitted if its value is 0. Also, using the from and to keywords is another way of writing 0% and 100%. And there goes our loader animation: I've tweaked the version that's displayed on this page a little bit, and distilled it down to the essential parts: .spinning-loader { width: 50px; height: 50px; border-radius: 50%; border: 5px solid rgba(29, 161, 242, 0.2); border-left-color: rgb(29, 161, 242); background: transparent; animation: rotate-s-loader 1s linear infinite; margin: 6rem auto; } @keyframes rotate-s-loader { from { transform: rotate(0); } to { transform: rotate(360deg); } }

    The Full Code at a Glance

    First, the HTML markup. As promised, only one div : <div class="spinning-loader"></div> And next comes the CSS styling: :root { --s-loader-wrapper-bg-color: rgb(21, 22, 43); --s-loader-width: 20px; --s-loader-height: var(--s-loader-width); --s-loader-border-color-trans: rgba(29, 161, 242, 0.2); --s-loader-border-color-full: rgb(29, 161, 242); } body { margin: 0; background: var(--s-loader-wrapper-bg-color, rgb(21, 22, 43)); height: 100vh; width: 100%; display: flex; align-items: center; justify-content: center; } .spinning-loader { width: var(--s-loader-width); height: var(--s-loader-height); border: 5px solid var(--s-loader-border-color-trans); border-left-color: var(--s-loader-border-color-full); border-radius: 50%; background: transparent; animation-name: rotate-s-loader; animation-iteration-count: infinite; animation-duration: 1s; animation-timing-function: linear; position: relative; } @keyframes rotate-s-loader { from { transform: rotate(0); } to { transform: rotate(360deg); } } And, there you have it! There are many ways of creating different kinds of loaders. This is just one of them. Once you start to break down the different parts that make up a loader, you can create them fairly easily. Of course, the only limit is your imagination . So there, I hope your spinner keeps on rotating!

    Introduction to Conic Gradients in CSS

    We can already do linear gradients and radial gradients with CSS quite easily, and now there's a 3rd type of gradient that will be defined in the spec. Conic gradients are similar to radial gradients, except that the color stops are on the outer edge of the circle that gets created. For example, here's a radial gradient and a conic gradient that have the same color stops: .gradient { width: 200px; height: 200px; border-radius: 50%; } .radial { background: radial-gradient(#FAE042, #4AAE9B); } .conic { background: conic-gradient(#FAE042, #4AAE9B); } And here's the markup: <div class="gradient radial"></div> <div class="gradient conic"></div>

    More Examples / Syntax

    Conic gradients can have multiple color stops: .conic { background: conic-gradient(cyan, magenta, yellow, black); }
    Each color can specify it's stop position using units such as degrees, turns or percentages: .conic { background: conic-gradient(red 180deg, #4AAE9B); } .conic-2 { background: conic-gradient(red 180deg 90%, #4AAE9B); } Notice how a second position value for a color stop specifies the transition.

    Hard stops

    The color stops can jump to the next color immediately by eliminating the transition between two stops: .conic-4 { background: conic-gradient(cyan 25%, magenta 0 50%, yellow 0 75%, black 0); }

    from and at Keywords

    You can specify the starting angle using the from keyword: .conic { background: conic-gradient(from 45deg, cyan, magenta, yellow); } Furthermore, you can use the at keyword to specify the center of the transition: .conic { background: conic-gradient(from 45deg at 65% 35%, cyan, magenta, yellow); } Unfortunately I can't show an example of using at at this moment because at the time of this writing there's a bug in the polyfill that would make all the other examples crash when viewed in a browser that relies on the polyfill.

    Smooth Transitions

    For smooth transitions, have the last color stop be the same as the first one: .conic { background: conic-gradient(cyan, magenta, yellow, cyan); }

    Repeating Conic Gradients

    There's also a repeating-conic-gradient function that can be used to create some interesting patterns with conic gradients: .conic-repeating { background: repeating-conic-gradient(red 10%, #4AAE9B 20%); }

    Polyfill

    Browser support for conic gradients is pretty bad right now, with native support only in Chrome 69+ at the time of this writing. Thankfully though, there's a polyfill by @LeaVerou that we can use to start using conic gradients now. To use the polyfill simply add the scripts for Prefix-free and the conic gradient polyfill itself before the closing body tag in your pages: <script src="/assets/polyfills/prefixfree.min.js"></script> <script src="/assets/polyfills/conic-gradient.js"></script> Browser Support Can I Use css-conic-gradients? Data on support for the css-conic-gradients feature across the major browsers from caniuse.com.

    Control Page Scroll in CSS Using Scroll Snapping

    Scroll snapping is a technique that you've certainly seen already. When implemented irresponsibly it can become extremely annoying and give a very bad browsing experience to the user. When done right though, it can be a great way to display things like image galleries. It used to be only achievable using JavaScript, but, thanks to the new CSS Scroll Snap module, the effect can now be controlled using CSS. The good news too is that browsers are still in control and can make a judgment call as to wether a snap point should be respected, given how the user is scrolling. This can help to avoid bad UX where snap points hinder a smooth navigation. Let's briefly go over how scroll snapping in CSS works.

    The Big Picture

    Similar to how CSS grid or Flexbox work, scroll snapping is done by defining a parent/container element and children within the container that will snap according to rules defined on the container. Some properties apply on the container element and some apply on the children.

    Container Element: scroll-snap-type

    The most important property that applies to the container element is the scroll-snap-type property. It effectively makes the element into a snap container and defines the scroll snap axis (x, y, block, inline or both) as well as the scroll snap strictness (none, proximity or mandatory). If, for example, you want a container that scrolls on the y axis and the snapping to happen no matter what, here's how you'd apply scroll-snap-type: .container { scroll-snap-type: y mandatory; } Or, if you want scroll snapping in both directions and less strictness on the snapping itself: .container { scroll-snap-type: both proximity; }

    scroll-padding

    Another property on the container is scroll-padding and it allows to set padding on the container to avoid having the snapping happen at the very edges of the container. The property expects values with the same syntax as the padding property.

    Child Elements: scroll-snap-align

    When it comes to the elements within a scroll container, the scroll-snap-align is probably the most important property. It can take a value of either none, start, end or center and specifies where in the element the snapping will occur, at the start, the center or the end. Depending on the scroll axis, and assuming a left-to-right text direction, the start can either be the top or the left and then the end can either be the bottom or the right. You'll probably always want to set a value for the element's scroll-snap-align because the initial value is none, meaning that no snapping will occur.

    scroll-margin

    Use scroll-margin the same with you'd use the margin property to set a different scroll snap area on the elements.

    scroll-snap-stop

    The scroll-snap-stop property can take a value of either normal or always and specifies if an element should force a snapping point, even if the user's scroll behavior would normally make the snapping be skipped. The initial value for that property is normal.

    Demos

    Now that we've gone over the theory and the different properties, let's demonstrate things with some simple demos. First, one where the scroll is on the y axis and the scroll strictness is set to mandatory. Here's the markup: <div class="container"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> </div> And here are the CSS rules: .container { scroll-snap-type: y mandatory; overflow-y: scroll; border: 2px solid var(--gs0); border-radius: 8px; height: 33vh; } .container div { scroll-snap-align: start; height: 33vh; display: flex; justify-content: center; align-items: center; font-size: 4rem; } .container div:nth-child(1) { background: hotpink; color: white; } .container div:nth-child(2) { background: azure; } .container div:nth-child(3) { background: blanchedalmond; } .container div:nth-child(4) { background: lightcoral; color: white; } And the result looks like this: 1 2 3 4
    Contrast that to instead setting a strictness of proximity, where snapping will only occur if scrolling stops within close range of a snap point: .container { /* ... */ scroll-snap-type: y proximity; overflow-y: scroll; } /* ... */ 1 2 3 4
    Finally, let's have a look at how things can look like when scroll snapping happens on both scrolling axes. An image gallery would be a perfect use case for something like that. Here our container will also happen to be a grid container. First, the markup: <div class="container2"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> </div> And now the styles: .container2 { display: grid; grid-template-columns: 100% 100% 100%; scroll-snap-type: both mandatory; overflow: scroll; border: 2px solid var(--gs0); border-radius: 8px; height: 33vh; } .container2 div { scroll-snap-align: start; height: 33vh; display: flex; justify-content: center; align-items: center; font-size: 4rem; } .container2 div:nth-child(1) { background: hotpink; color: white; } .container2 div:nth-child(2) { background: azure; } .container2 div:nth-child(3) { background: blanchedalmond; } .container2 div:nth-child(4) { background: lightcoral; color: white; } .container2 div:nth-child(5) { background: rebeccapurple; color: white; } /* ...you get the point */ Which results in the following: 1 2 3 4 5 6 7 8 9

    Further Reading

    This article scratched the surface and introduced you to the syntax, and here are some excellent posts if you're interested in digging deeper into use cases and see some more examples:
  • Practical CSS Scroll Snapping
  • Well-Controlled Scrolling with CSS Scroll Snap
  • Browser Support Can I Use css-snappoints? Data on support for the css-snappoints feature across the major browsers from caniuse.com.

    Drop Caps in CSS Using first-letter & initial-letter

    Drop caps have been used for a long time with print media to give panache to the first letter of the first paragraph of a section or chapter. These drop caps help draw attention and entice the reader, and it's often a good occasion to use a very stylized font because it's applied on only one letter so it won't affect the text's readability. The same drop cap effect can be accomplished with CSS using the ::first-letter pseudo element and the new initial-letter property.

    ::first-letter Pseudo Element Selector

    ::first-letter is a pseudo element selector similar to ::before and ::after that effectively makes the first letter of an element stylable as if it was its own distinct element, all without having to add any additional markup to your pages. Here's a simple example where we style the 1st letter of the 1st paragraph or article elements: article p:first-child::first-letter { color: hotpink; padding: 0 .3rem; margin: 0 .3rem 0 0; border: 2px solid; border-radius: 8px; font-family: "IBM Plex Mono", monospace; } And with this, we get something that looks like this: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ante turpis, rhoncus vel nisi eu, congue iaculis neque. Nunc bibendum dui felis, et auctor mi maximus in. Vestibulum porta orci et ex mattis, sit amet feugiat justo fermentum. Duis blandit tempor purus at elementum. In id consequat lorem.
    There's trouble in paradise though. Look at what happens if we for a larger font size; one of the main features of a typical drop cap: article p:first-child::first-letter { color: hotpink; padding: 0 .3rem; margin: 0 .3rem 0 0; border: 2px solid; border-radius: 8px; font-family: "IBM Plex Mono"; font-size: 4rem; line-height: 1; } Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ante turpis, rhoncus vel nisi eu, congue iaculis neque. Nunc bibendum dui felis, et auctor mi maximus in. Vestibulum porta orci et ex mattis, sit amet feugiat justo fermentum. Duis blandit tempor purus at elementum. In id consequat lorem. On top of using a larger font size, we also set a low value for line-height in order for the line height of the first line not to be influenced by this first letter's initial line height given the larger font. The problem is that the drop cap doesn't exactly drop. One solution is to use good old floats: article p:first-child::first-letter { color: hotpink; padding: 0 .3rem; margin: 0 .3rem 0 0; border: 2px solid; border-radius: 8px; font-family: "IBM Plex Mono", monospace; font-size: 4rem; float: left; line-height: 1; } Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ante turpis, rhoncus vel nisi eu, congue iaculis neque. Nunc bibendum dui felis, et auctor mi maximus in. Vestibulum porta orci et ex mattis, sit amet feugiat justo fermentum. Duis blandit tempor purus at elementum. In id consequat lorem. Browser support for ::first-letter is pretty much universal.

    initial-letter Property

    An alternative to using floats along with line-height and font-size to properly style drop caps is to use the new initial-letter property, which expects a number value that represents the number of lines that the drop cap should extend to. The browser then calculates the proper font size automatically: article p:first-child::first-letter { color: hotpink; padding-right: 8px; -webkit-initial-letter: 3; initial-letter: 3; } Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse ante turpis, rhoncus vel nisi eu, congue iaculis neque. Nunc bibendum dui felis, et auctor mi maximus in. Vestibulum porta orci et ex mattis, sit amet feugiat justo fermentum. Duis blandit tempor purus at elementum. In id consequat lorem. At the time of this writing, this last demo will only work as expected in Safari. Unlike with ::first-letter, the support for initial-letter is almost non-existent at the moment unfortunately. So for now we'll have to keep using floats for a good little while. If you still want to use initial-letter, you'll probably want to use it with a @supports at-rule so that the drop cap doesn't look all kinds of odd in non-supporting browsers.

    Variable Fonts on the Web Using CSS

    Font variations is a new set of features defined as part of the OpenType specification. It allows for font files to contain multiple variation of a font within a single file, called a variable font. This in turns allows the use of one font file on the web that can achieve multiple font styles. On top of the obvious savings in turns of data that needs to be sent over the wire to display the text on a page, variable fonts enable features such as animating or transitioning font styles and custom font styles, both of which are not possible with static fonts. Let's go over some examples of using a variable font, and then break down how to use them on the web today.

    Variable Font Examples

    Note that you'll need to use a supporting browser to properly view the examples below.

    Source Sans Variable

    Source Sans is a popular free font that now comes with in a variable version. Hover over the text to see how the value for font-weight can be transitioned:

    Well hello there Alligator

    How are you doing

    Very well, thank you

    And this is achieved using some very simple CSS rules: @font-face { font-family: 'Source Sans'; src: url('/assets/fonts/variable/SourceSansVariable-Roman.ttf') format("truetype-variations"); font-weight: 1 999; } .source-sans, .source-sans2, .source-sans3 { font-family: 'Source Sans'; transition: font-weight .45s ease-out; } .source-sans:hover, .source-sans2:hover { font-weight: 999; } .source-sans3:hover { font-weight: 200; }

    Custom font styles

    Here are some examples all using the same font, Decovar, a variable font that defines custom axes and allows for unique and stylized text:

    Well hello there Alligator

    How are you doing

    Very well, thank you

    And here's the CSS rules used for that: @font-face { font-family: Decovar; src: url('/assets/fonts/variable/DecovarAlpha-VF.subset.ttf') format("truetype-variations"); } .decovar, .decovar2, .decovar3 { font-family: Decovar; } .decovar { color: var(--green3); font-variation-settings: "BLDA" 506.944, "TRMC" 1000, "TRMK" 324.653; } .decovar2 { color: hotpink; font-variation-settings: "WMX2" 580.838, "TRMB" 1000; } .decovar3 { color: rebeccapurple; font-variation-settings: "TRMF" 159.18, "TRME" 1000; }
    Now that you've seen some real-life examples, let's go over some of the concepts and how to make use of variable fonts in your own web pages.

    Font Axes

    Variable fonts define their variations though axes of variation. There are 5 standard axes:
  • ital: Controls the italics. The value can be set using the font-style CSS property.
  • opsz: Controls the font's optical size. The value can be set using the font-optical-sizing CSS property.
  • slnt: Controls the slant of the font. The value can be set using the font-style CSS property.
  • wght: Controls the font's weight. The value can be set using the font-weight CSS property.
  • wdth: Controls the font's width. The value can be set using the font-stretch CSS property.
  • Fonts can also specify custom axes, and these need to have a 4-letter uppercase name instead of the 4-letter lowercase names of the standard axes. The Decovar font demoed above is a prime example of a font using a multitude of custom axes. The standard axes can be set with well-known CSS properties (e.g.: wdth is set with font-weight), and the new CSS font-variation-settings is used to control the values for axes otherwise. For example, here we define a style for the NobotoFlex variable font: h1 { font-variation-settings: "BASE" 500, "SPAC" 200, "wght" 322, "HEIG" 456; } Which could have alternatively been defined like this: h1 { font-weight: 322 font-variation-settings: "BASE" 500, "SPAC" 200, "HEIG" 456; } It's a good idea to use the native CSS properties for the axes that have one. Note that fonts don't have to implement all 5 standard axes, and instead you should consult the documentation of the font to know what axes you can control. Note also how font-weight can take values anywhere between 1 and 999, compared to the 100-value increments we're used to.

    Using Variable Fonts with @font-face

    Using variable fonts on the web involves defining @font-face rules that point to the variable font files. The following is a brief overview of how it's done, but for there are a few caveats you may want to learn about for cross-browser support. Here for example we define two version for the Source Sans font family, one regular and one bold. Both versions make use of the same variable font file, but different font files as a fallback for browsers that don't support variable fonts: @font-face { font-family: 'Source Sans'; src: url('/path/to/SourceSansVariable.woff2') format("woff2-variations"); src: url('/path/to/SourceSans.woff2') format("woff2"); font-weight: 400; } @font-face { font-family: 'Source Sans'; src: url('/path/to/SourceSansVariable.woff2') format("woff2-variations"); src: url('/path/to/SourceSansBold.woff2') format("woff2"); font-weight: 900; } And it can now be used within your CSS rules as usual: h1 { font-family: 'Source Sans'; font-weight: 900; } h3 { font-family: 'Source Sans'; font-weight: 400; }
    You can also specify a range in your @font-face rules, to retain the ability to use all the possible values within your regular CSS rules: @font-face { font-family: 'Source Sans'; src: url('/path/to/SourceSansVariable.woff2') format("woff2-variations"); src: url('/path/to/SourceSans.woff2') format("woff2"); font-weight: 1 999; } With the above, we can now use any value between 1 and 999 for the font-weight property. Non-supporting browsers will use a font-weight value of normal.

    Available Fonts

    You can find and play with most of the currently available variable fonts on V-fonts.com. A few notable Open Source ones are Barlow, Mutador Sans, Source Sans, Amstelvar and Cabin VF. Some are also available through Google Fonts as early access fonts.

    TTF to WOFF2

    Font files will often be provided in the TrueType format (ttf), but for the web it's a much better idea to compress the font file to the WOFF2 format, to save on space. You can use a tool like FontTools to compress a font file as WOFF2. More user-friendly GUI or online tools will surely become available really soon.

    Browser Support

    Support for variable fonts is already pretty good, so in theory you can start using them today. There are a few caveats with support however, and some things are still being ironed-out for their usage within CSS as part of the CSS Fonts Module Level 4. Here's a nice summary what's still in flux at the moment.

    Resources and Tools

    Here's some further reading material if you want to expand your understanding of using variable fonts on the web:
  • Get started with variable fonts by Richard Rutter
  • Introduction to variable fonts on the web
  • One File, Many Options: Using Variable Fonts on the Web
  • And here are two tools that allow you to easily test out and find variable fonts:
  • Axis-Praxis
  • V-Fonts.com
  • Browser Support Can I Use variable-fonts? Data on support for the variable-fonts feature across the major browsers from caniuse.com.

    CSS Media Queries: Quick Reference & Guide

    Media queries give us a very powerful way to adjust our styles according to factors like the type of device used, the viewport size, the screen's pixel density, or even the device orientation. As media queries have been around for quite a while, you may already be familiar with the basic syntax and usage. This post therefore aims to be a good quick reference point, and hopefully you'll also discover a few tricks you didn't know were possible.

    Basic Media Queries

    Media queries are defined using the @media at-rule followed by a media type, 0 or more media features or both a media type and media feature(s). The available media types are all, print, screen and speech, and when not specified the type of all is implied. Multiple media types can be used at once and they should be separated by commas: @media screen, print { /* Styles for screen and print devices */ } Media types such as tv or projection have been deprecated with Media Queries level 4. As for media features, they are defined in parentheses and a vast array of features can be tested. Some of the most popular features are width, height, aspect-ratio, orientation and resolution. Many of these popular features are range features so they also have a min and max version available (eg.: min-width, max-width, min-aspect-ratio, max-aspect-ratio,…) In the following simple example, the default background color is hotpink, but screen devices with a viewport width that's 650px or less will have a background color of rebeccapurple instead: body { background: hotpink; } @media screen and (max-width: 650px) { body { background: rebeccapurple; } } Notice how, when specifying both a media type and a media feature, we need to use the and logical operator between them.
    Here are a few more examples of simple media queries that specify either a media type, a media feature or both: @media print { /* styles for print media only */ } @media (max-width: 65rem) { /* styles for any device that has a display width of 65rem or less */ } @media screen and (min-width: 800px) { /* styles for screen viewports that have a width of 800px or more */ }

    Multiple Media Features

    You can specify multiple media feature requirements to satisfy the media query using the and logical operator between features. When using and, the query will match only if all the features evaluate to true. For example, it's very common to have layouts that adjust to a few different ranges of viewport widths: /* Extra-small */ @media screen and (max-width: 360px) { /* ... */ } /* Small */ @media screen and (min-width: 361px) and (max-width: 480px) { /* ... */ } /* Medium-only */ @media screen and (min-width: 481px) and (max-width: 960px) { /* ... */ } /* ... */

    Or Logical Operator Using Commas

    You can define multiple queries separated by commas, in which case the commas act as logical or operators and the query becomes a list of queries. The media query will apply if any of the comma separated queries matches. In the following example, the media query will be true if the device has an orientation of portrait or if the device's viewport has a min-width of 3rem and a max-aspect-ratio of 2/1: @media (orientation: portrait), (min-width: 3rem) and (max-aspect-ratio: 2/1) { /* ... */ }

    Not Logical Operator

    You can use the not logical operator at the beginning of a query to toggle the truthiness of the whole query. The not operator is useful to apply styles when certain conditions are not met by the browser or device. In the following example, the media query will apply when the primary pointing device can't hover on elements: @media not screen and (hover: hover) { /* ... */ } Note that with not the media type is not optional. Also, not doesn't negate an entire query list (queries separated with commas), but only one query.

    Only Logical Operator

    The only logical operator is a little bit special and hides the entire query for older browsers. In other words, older browsers don't understand the only keyword so the entire media query is ignored. Otherwise only has not effect: @media only all and (min-width: 320px) and (max-width: 480px) { /* ignored by older browsers */ } As with the not operator, the media type is not optional when using only. Note that legacy browsers that don't support Media Queries level 3 are rare now so in most cases the use of only is unnecessary.

    Additions from Media Queries Level 4

    The latest edition of the media query spec (level 4) specifies quite a few new media features that can be tested:
  • pointer: If there's a primary pointing device (none, coarse or fine).
  • any-pointer: If there's any pointing device available (none, coarse or fine).
  • hover: Can the primary pointing device hover on elements (none or hover).
  • any-hover: Can any of the available pointing devices hover on elements (none or hover).
  • color-gamut: The range of available colors (srgb, p3 or rec2020).
  • overflow-inline: How potential overflow on the inline axis is treated (none, paged, optional-paged or scroll).
  • overflow-block: How potential overflow on the block axis is treated (none, paged, optional-paged or scroll).
  • update: At which frequency the layout can be updated (none, slow or fast).
  • Media Queries for Retina Displays

    Over the last few years we've started to see a proliferation of devices with displays that have a higher pixel density. It can be useful to style certain aspects of your designs differently for devices with these higher pixel densities. A good example would be providing high-resolution version of certain graphics. We can accomplish this using the min-resolution media feature with a value of 192dpi. However, the resolution feature is not necessarily supported across all browsers and for a more foolproof approach we can also add an additional non-standard -webkit-min-device-pixel-ratio feature with a value of 2: @media screen and (min-resolution: 192dpi), (-webkit-min-device-pixel-ratio: 2) { /* ... */ } You can track the current browser support for the resolution media feature on Can I Use.

    Resources

    Below are a few very useful media query-related resources:
  • CSS-Tricks' Media Queries for Standard Devices.
  • MQTest.io, to test which media features your device responds to.
  • MDN's reference of available media features.
  • Creating Patterns Using CSS & the <css-doodle /> Web Component

    <css-doodle /> is a Web Component that makes it easy to create all kinds of patterns for your web designs. It's a great example of what can be achieved using modern web technologies like custom elements, shadow DOM and CSS Grid. You can see an example of <css-doodle /> in action at the top of category pages on this site.

    Setup

    You can simply include the <css-doodle /> script from cdnjs into your pages: <script src="https://cdnjs.cloudflare.com/ajax/libs/css-doodle/0.2.3/css-doodle.min.js"></script> Alternatively, you can also add the component to your project using Yarn or npm: $ npm install css-doodle # or, using Yarn: $ yarn add css-doodle Then you can simply add pattern sections to your pages using the <css-doodle /> custom element with some CSS rules passed-in as children: <css-doodle> ... </css-doodle>

    Basic Examples

    Behind the scenes <css-doodle /> creates a grid of elements using CSS Grid layout. Let's create a simple grid of 5 rows by 8 columns with a width value that's 100% the width of its parent container and a height of 15rem: :doodle { @grid: 5x8 / 100% 15rem; } :after { content: "@index()" } background: pink; margin: .5rem; <css-doodle> :doodle { @grid: 5x8 / 100% 15rem; } :after { content: "@index()" } background: pink; margin: .5rem; </css-doodle> Notice how we get a special :doodle pseudo-selector to style the grid container itself. Within that pseudo-selector we used the @grid attribute to define the number of cells in the grid and the total size of the grid container. You can also see that we made use of another special function, @index(), to add the current cell index as the content to each cell's :after pseudo-element. You can also define the number of cells using the grid attribute on the element directly: <css-doodle grid="5x8"> ... </css-doodle>
    Let's now push this example a little bit further to create an interesting pattern: :doodle { @grid: 8 / 25rem 25rem; @shape: circle; background: var(--bg3); max-width: 90%; } @keyframes turn { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes glow { 50% { transform: scale(1.1); } 100% { transform: scale(1); } } @random { animation: glow .9s ease-out infinite; } :hover { animation: turn .9s ease-out infinite; } @shape: @pick('triangle', 'clover 4', 'hexagon', 'diamond', 'heart'); background: @pick('coral', 'orange', 'pink', 'blueviolet', 'darkslateblue'); margin: .5rem; opacity: calc(@rand(1, 10) / 10); <css-doodle> :doodle { @grid: 8 / 20rem 20rem; @shape: circle; background: var(--bg3); max-width: 90%; } @keyframes turn { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes glow { 50% { transform: scale(1.1); } 100% { transform: scale(1); } } @random { animation: glow .9s ease-out infinite; } :hover { animation: turn .9s ease-out infinite; } @shape: @pick('triangle', 'clover 4', 'hexagon', 'diamond', 'heart'); background: @pick('coral', 'orange', 'pink', 'blueviolet', 'darkslateblue'); margin: .5rem; opacity: calc(@rand(1, 10) / 10); </css-doodle> That example is a lot more interesting, yet still quite simple to implement. We made use of a few more special functions that are made available by <css-doodle />:
  • @shape: Allows to shape the cell or the container using any of a number of predefined shapes.
  • @pick: Picks one of the provided values at random.
  • @rand: Returns a random value between the provided range.
  • And we also made use of another special selector:
  • @random: Selects some cells at random.
  • As you can see, the component also accepts any valid CSS rules, even our animation definition using @keyframes. Our global CSS variables are also accessible. There's quite a few more special selectors, properties and functions that are available, making it possible to create pretty much any pattern imaginable. Have a look at the official docs for a full reference.

    JavaScript API

    There's a simple JavaScript API that lets you get or set the number of rows and columns or update the doodle with new values. For example, let's create a simple doodle that refreshes its value when clicked on: :doodle { @grid: 8 / 25rem 25rem; @shape: circle; background: var(--bg3); max-width: 90%; } @keyframes turn { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } :hover { animation: turn .9s ease-out infinite; } @shape: @pick('triangle', 'clover 4', 'hexagon', 'diamond', 'heart'); background: @pick('coral', 'orange', 'pink', 'blueviolet', 'darkslateblue'); margin: .5rem; opacity: calc(@rand(1, 10) / 10); <css-doodle class="my-doodle"> ... </css-doodle> <script> const myDoodle = document.querySelector('.my-doodle'); myDoodle.addEventListener('click', () => { myDoodle.update(); }); </script> Since our doodle contained values for cell shape and opacity that are picked at random, updating it changes the pattern each time.

    Browser Support

    Currently <css-doodle /> works out of the box in Chrome and Safari without the need for any polyfill. To make it work in non-supporting browsers, refer to this article about polyfilling for custom elements. Alternatively, you may want to opt for graceful degradation and just hide your patterns on non-supporting browsers. For example, the following adds a no-doodle-support class to the body element if custom elements or shadow DOM are not supported: if (!window.customElements || !document.head.attachShadow) { document.body.classList.add('no-doodle-support'); } Then you can simply set display: none on the css-doodle elements that are within a body with the no-doodle-support class: .no-doodle-support css-doodle { display: none; }

    Further Reading

    Check out the following links to learn more:
  • Official Repo
  • Creating patterns using Unicode characters
  • Codepen collection of Unicode patterns
  • CSS transform-origin Property

    The CSS transform-origin property, as its name implies, defines where a transform originates from. The initial (default) value for transform-origin is 50% 50% 0, which is the center of the element. A transform that originates from the center is often what we're after, but the property can come-in handy if you're trying to create transforms that are a little more intricate. You can define an origin for the horizontal as well as for the vertical axis, and if only one value is provided it will be applied to both axes. Values can be provided as length values (px, em,…), percentage values (%) or as keyword values between the following:
  • top
  • right
  • center
  • bottom
  • left
  • When unit values are provided, the first value is for the horizontal axis (x-offset) and the second is for the vertical axis (y-offset). For example, the following will place the center of rotation at 50% on the horizontal axis and 85% on the vertical axis: .some-element { transform: rotate(75deg); transform-origin: 50% 85%; } When using keyword values, you can provide the values in a different axis order if there can be no confusion between the two. For example, the following is valid: .some-element { transform: rotate(75deg); transform-origin: top left; }

    3D transforms

    A third value can also be provided for the offset on the z-axis, which is handy for 3D transforms: .some-fancy-element { transform: rotate3d(-1, 2, 1, 30deg); transform-origin: 10% 80% 140px; } Note that the 3rd value (the z-offset) has to be a length and can't be a percentage value.

    Simple Example

    Here's a simple example to illustrate where we have three images with a rotation transform applied (transform: rotate(…)). You can use the slider to change the degrees of rotation and the little fuchsia dots show where the transform origin is located for each image: With transform-origin at 50% 50% with transform-origin at 10% 20% with transform-origin at top right As you can see the effect of the rotation is different for all three images, due to the different values of their transform-origin property. Or first image doesn't use a value so the initial value is being used (50% 50% 0), our second uses a value of 10% 70% for an origin that's 10% on the horizontal axis and 70% from the vertical axis, and our third image uses a value of top right: .example-1, .example-2, .example-3 { transform: rotate(45deg); } .example-2 { transform-origin: 10% 70%; } .example-3 { transform-origin: top right; }

    A Look at CSS Viewport Units

    Viewport units were introduced with the CSS Values and Units level 3 spec. They allow to size elements and font sizes as a percentage of the total width or height of the user's screen (the viewport). Let's explore what we can accomplish design-wise by making use of these units in our CSS.

    vh & vw

    vh stands for viewport height and vw is for viewport width. Hence, setting an element to a width value of 50vw means that the element will have a width that's 50% of the viewport size, and this stays true when the viewport is resized. Screen mockup demonstrating viewport unit placement

    Percentage vs Viewport Units

    Since viewport units are a percentage of the size of the viewport, it can seem at first glance that specifying sizes as percentage values would be equivalent. The difference is that viewport units are always a percentage of the total size of the viewport, while a percentage value applied on an element is a percentage of the element's parent, not necessarily the whole viewport.

    vmin & vmax

    vmin and vmax might seem a little trickier to understand, but it's all really simple in the end. With vmin, we size as a percentage of the smallest between the width or the height of the viewport, and with vmax, we size as a percentage of the largest between the two. Say, for example, that our viewport is 1440px wide and 800px tall, if we set element to have a width of 50vmin, it'll be 50% of the height (400px), and if instead we set the element to have a width of 50vmax, it'll be 50% of the width (720px). If the viewport was instead 800px width and 1440px tall, we'd get the exact opposite result. vmin and vmax can be useful to size title font sizes as we'll illustrate below.

    Viewport Units for Hero Sections

    Viewport units are great to help create hero sections that take up the exact height of the viewport. Let's create an example to illustrate. Say we want to create 2 sections that both take up the full width of the viewport and that together take up the full height of the viewport. First, some simple markup for our sections: <section class="hero"> <h1>I'm a Hero Title</h1> </section> <section class="sub-hero"> <h1>I'm the Subhero</h1> </section> And then our styles: .hero { height: 75vh; background: linear-gradient(45deg, #DA4453, #89216B); } .sub-hero { height: 25vh; background: linear-gradient(115deg, #4e54c8, #8f94fb); } .hero, .sub-hero { display: flex; align-items: center; justify-content: center; width: 100vw; position: relative; left: 50%; margin-left: -50vw; } Now, pulling off the two sections together taking up the full height is easy: 75vh for the hero section and 25vh for the sub-hero section. But articles on this site are inside a container with a max-width value of 55rem, so it gets trickier here for our sections to break out of the container. Applying a width of 100vw alone doesn't do the trick because the elements still start on the left edge of the parent container. Thanks to a trick demonstrated in this pen by Sven Wolfermann, and explained in this CSS-Tricks article, we can make use of viewport units once again to effectively breakout of the container element and take up the full width of the viewport. It involves pushing the element to the center of the viewport and then pulling it back using a negative margin of -50vw.

    Here's the result:

    I'm a Hero Title

    I'm the Subhero


    Try resizing your browser window and notice how the sections always take up the exact width and height of the viewport

    Hero section with a navbar

    Say you want to design a hero section that takes up the fullwidth of the viewport and the full height, minus the height of your site's navbar. If you know the height of the navbar, that's easy to do using the calc() function. Say, for example, that our navbar has a height of 3rem: .hero { height: calc(100vh - 3rem); width: 100vw; }

    Vertical scrollbar caveat

    If your operating system is set to always show scrollbars, you may face a problem where 100vw doesn't take into account the visible scrollbar and you end up with some horizontal scrolling because of 100vw being slightly wider than the viewport minus the scrollbar width. Answers to this Stack Overflow question give out a few possible solutions. For the example in this post, I fixed the problem by adding overflow-x: hidden to the both the html and body elements: html, body { overflow-x: hidden; } Thanks to Michael Coker for pointing out this problem!

    Viewport Units for Titles

    Viewport units are not only great for large elements like hero sections, but they can also be used to size elements like titles and have their font size adjust automatically as a function of the viewport size. This way, we can potentially avoid having to set multiple breakpoints with set font sizes, which can simplify our style rules. Here for example we have a title width a font-size of 5vw: h1 { font-size: 5vw; text-align: center; }

    I'm a Title at 5vw

    It works and our title will be larger on large viewports and smaller on small viewports. One problem is that the title may become too large on very large viewports and too small on very small viewports. Because of that, we may still have to use breakpoints to define static font size values for viewports over or under a certain size. Or, in this case, we can fix part of the problem by making use of the vmax unit to ensure that our title doesn't become too little. Here our title will have a font size of 4% of the largest between the width or the height of the viewport: h1 { font-size: 4vmax; text-align: center; }

    I'm a Title at 4vmax

    Browser Support Can I Use viewport-units? Data on support for the viewport-units feature across the major browsers from caniuse.com.

    Making Elements Stick in CSS Using position: sticky

    There's a new value in town for the CSS position property: sticky. It allows us to make elements stick when the scroll reaches a certain point. An element with position: sticky will behave like a relatively-positioned element until it reaches a specified point and then starts behaving like a statically-positioned element. In this post we'll create a simple example to illustrate. We'll have a div container that will be a flex container and then 4 additional div elements that will be the flex items. Note we don't have to use flexbox at all for position: sticky to work, here it's just that flexbox happens to work great for our example. Check our flexbox primer if you'd like a refresher on the different flexbox properties and values. Here's the simple markup: <div class="container"> <div class="item pirate"> <img src="/images/pirate.svg" width="100" alt="Item 1"> </div> <div class="item police"> <img src="/images/police.svg" width="100" alt="Item 2"> </div> <div class="item cowboy"> <img src="/images/cowboy.svg" width="100" alt="Item 3"> </div> <div class="item doctor"> <img src="/images/doctor.svg" width="100" alt="Item 4"> </div> </div> And now our styles, with the important rules highlighted: .container { display: flex; justify-content: space-around; align-items: flex-start; border: 2px dashed rgba(114, 186, 94, 0.35); height: 400px; background: rgba(114, 186, 94, 0.05); } .pirate { position: -webkit-sticky; position: sticky; top: 4rem; } .police { position: -webkit-sticky; position: sticky; top: 0; } .doctor { position: -webkit-sticky; position: sticky; bottom: 1rem; align-self: flex-end; } And here's the result. Try scrolling the page up and down to notice what happens: Item 1 Item 2 Item 3 Item 4 Pretty neat hey! Such effect used to only be achievable using some JavaScript and registering a scroll handler. Here are a few additional things to note:
  • With our example, the align-items: flex-start rule on the flex container is important because otherwise flex items default to a value of stretch where the elements would take the whole height of the container, cancelling the sticky effect.
  • We need to make use of the -webkit-sticky vendor prefix for it to work in Safari.
  • It's important that you set a point for the element to become sticky using either of the top, bottom, left or right properties, depending on which direction the user will scroll.
  • Notice how sticky-positioned elements are only sticky within their parent element.
  • Have a look at our resources page for a real life example of how position: sticky can be used to accomplish a nice effect with nothing but CSS. Browser Support Can I Use css-sticky? Data on support for the css-sticky feature across the major browsers from caniuse.com.

    CSS Tip: Multicolor & Cutout Drop Shadows

    Joshua Bemenderfer Box shadows are boring. You heard me. They can only use one color at a time and are slow to animate or transition. You know what would be neat? Making a drop shadow that would use the colors of the element's background. So if the top left corner of your element was red, the top left corner of the shadow would be red. If the bottom right corner was blue, the bottom left corner of the shadow would be blue. Wouldn't that be neat? Too bad there's no way to do it in CSS… Oh wait, there is. Let's dive in.

    The Method

    Really, all we have to do is create a pseudo-element directly behind the parent element and have it inherit relevant properties, such as background and border-radius. Then we add a CSS blur() filter. This creates a second copy of the element's background and blurs it behind the element. Easy as pie. By inheriting the background and related properties, we don't have to specify them repeatedly. Even better, if you want to animate / smoosh / squash the shadow in some way, you have the full power of CSS transforms and opacity available to you on the pseudo-element! What's the catch? The shadow won't display in browsers that don't support the CSS blur filter.

    The Code

    /* The element that will have the blurred shadow. */ .fancy-box { /* We need to set the position value to something other than `static` * so that position: absolute for the pseudo-element will be relative * to this element. */ position: relative; /* A nice Alligator.io-themed linear gradient. */ /* This technique works with any and every background type. */ background: linear-gradient(to bottom right, rgb(107,183,86), rgb(0,143,104)); /* Whatever else you want in here. */ } /* The shadow pseudo-element. */ .fancy-box::before { content: ' '; /* Position it behind the parent. */ z-index: -1; position: absolute; top: 0; right: 0; bottom: 0; left: 0; /* Inherit the background and border radius of the parent. */ background: inherit; border-radius: inherit; /* Blur it for maximum shadowy-ness. */ filter: blur(15px); /* Hide the shadow until the element is hovered over. */ opacity: 0; transition: opacity 300ms; } /* Show the shadow on hover. */ .fancy-box:hover::before { opacity: 1; }

    The Result

    Note how it even works with transparent images! You can finally make shaped shadows!

    CSS Tip: Performant Box-Shadow Transitions

    Joshua Bemenderfer Have you ever been using a Material Design web app and thought “this just feels slow”? It might be because, well, it was. Material Design relies heavily on shadows to indicate depth and relationships. As AirBnB discovered, box shadows are slow. To make matters worse, animating shadow blur to make an element feel like it's moving forward and backward is a design pattern seen all over the place. Shadows cause a repaint on every frame they're changed, so shadow transitions are incredibly slow. Perhaps it's not too bad on a decently-powered computer, but you can often feel it on a mobile device. Let's take a look at an alternative, higher-performance method to create a nearly-equivalent effect. This method works best if you start with a subtle shadow. It may not be a fit for all use-cases.

    The Method

    What we're going to do is create the initial box-shadow on the element as normal, then create a pseudo-element that has the expanded shadow. The pseudo-element will be hidden with opacity: 0;. To transition to the expanded shadow, we'll just animate the opacity of the pseudo-element. Note, this is not a perfect replacement. The original shadow is still present, so the inner sides of the shadow are a little darker than you might expect. That's why this method works best when you go from a really subtle shadow to a much thicker one.

    The code

    /* The old, slow way. */ .slow-transition { box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3); transition: box-shadow 500ms; } .slow-transition:hover { box-shadow: 0 10px 50px 0 rgba(0, 0, 0, 0.5); } /* The fast, new way! */ .fast-transition { position: relative; /* For positioning the pseudo-element */ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3); } .fast-transition::before { /* Position the pseudo-element. */ content: ' '; position: absolute; top: 0; right: 0; bottom: 0; left: 0; /* Create the box shadow at expanded size. */ box-shadow: 0 10px 50px 0 rgba(0, 0, 0, 0.5); /* Hidden by default. */ opacity: 0; transition: opacity 500ms; } .fast-transition:hover::before { /* Show the pseudo-element on hover. */ opacity: 1; }

    The result and live demo

    Here's a codepen you can play around with.
    Normal Box Shadow Transition (Slower) Pseudo-Element Opacity Transition (Faster)

    Performance Details

    Okay, so I've told you one is faster, and one is slower, right? But why? The key to the performance difference is that transitioning box-shadow requires a repaint and recomposite on every frame, while transitioning opacity only requires recompositing (in most browsers). Here are the profiling results from my browser: Transitioning box-shadow:
  • Paint Time: ~6ms (varies)
  • Number of paints: 1 per frame.
  • Transitioning Pseudo-Element Opacity:
  • Paint Time: ~1.5ms
  • Number of Paints: 2 total.
  • Credits:
  • Tobias Ahlin for the original idea.
  • Centering Things in CSS Using Flexbox

    Centering of elements on a page, especially vertical centering, has been notoriously difficult to do in the past with CSS and we've had to resolve to a number of hacks. Thankfully though, Flexbox makes it all easier, and we can now instead focus our designing energy towards higher level problems. The following is a very simple guide on centering elements using Flexbox.

    Horizontal Centering

    Let's start with a div that contains two paragraphs that we want to center horizontally on the same axis. It's as easy as using the justify-content property with a value of center on the container: Example image arrr! Example image 2 yeehaw! <div class="box flex"> <p> <img src="https://alligator.io/css//images/pirate.svg" width="75"> arrr! </p> <p> <img src="https://alligator.io/css//images/cowboy.svg" width="75"> yeehaw! </p> </div> .box.flex { display: flex; justify-content: center; } .box { padding: .5rem; height: 300px; box-shadow: 2px 2px 5px rgba(0,0,0,0.03); border-radius: 4px; color: #84613D; font-family: "Lucida Console", Monaco, monospace; background: #FDF9EA; border-bottom: 1px solid #F9F2D6; border-right: 1px solid #F9F2D6; } .box p { max-width: 125px; text-align: center; background: rgba(255,255,255,0.5); margin: .25rem; padding: .25rem; }

    Vertical Centering

    The power of Flexbox really shines when we also need to center elements vertically. Here's our example, but with the flex items also centered vertically: .box.flex { display: flex; justify-content: center; align-items: center; } Example image arrr! Example image yeehaw! If you just want specific flex items to be centered vertically, you can set align-self on the items instead: .flex p:last-child { align-self: center; } Example image arrr! Example image yeehaw!

    Vertical Centering On Whole Page

    If you want to put an element at the dead center of a page, it can be a little bit more tricky because flex items will only center vertically according to the height of their container. That means that the container itself needs to be the same height as the page itself. That easy-enough to do using viewport units, where 100vh is 100% of the height of the viewport. Here's a simple example: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dead center!</title> <style> body { margin: 0; } .center-me { display: flex; justify-content: center; align-items: center; height: 100vh; } </style> </head> <body> <div class="center-me"> <p> Bonjour center!</p> </div> </body> </html> Notice also that we make sure to reset the page's margin to 0, as otherwise you'd end up with a little bit of a scroll.

    Exploring Multi-Column Layouts in CSS

    Layouts where content flows between multiple columns and multi-column magazine-style layouts can now easily be implemented in CSS using a few simple rules defined as part of the CSS Multi-column Layout specification. This, along with CSS grid and flexbox, really allows us to define pretty much any kind of layout with minimum effort. Let's go over what's currently possible in terms of multi-column layouts.

    Basic Multi-Column Layouts

    Multi-column layouts are defined with either the column-count or the column-width properties set on a containing block element.

    column-count

    column-count takes an integer value for the number of columns that the block element should have: .col { background: var(--subtle-yellow2); padding: 1rem 2rem; } .col-3 { column-count: 3; } <article class="col col-3"> <p>...</p> <p>...</p> <p>...</p> </article>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede. Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. To create a responsive layout, it's as simple as setting a different number of columns on smaller viewports: @media (max-width: 600px) { .col-3 { column-count: 1; } } @media (min-width: 601px) and (max-width: 900px) { .col-3 { column-count: 2; } }

    column-width

    With column-width, instead of providing an exact number of columns, you provide a suggested width for them and the number of columns will be computed against that and the available space. Here's an example where columns have a width of 8rem: .col-8rem { column-width: 8rem; } <article class="col col-8rem"> <p>...</p> <p>...</p> <p>...</p> </article>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede. Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.
    If you resize your viewport you'll notice that using column-width will make the multi-column layout responsive by default without the need to define a different number of columns for smaller viewports.

    columns

    There's also a shorthand property for column-count and column-with called columns. Here's how you would set a container to have 2 columns or columns with a width of 12rem: .col-2-12rem { columns: 2 12rem; }
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede. Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.
    Setting both a column count and a column width is perhaps a bit odd for most use cases, because it's then left to the browser to decide to follow either the provided count or the width.

    Gaps & Rules

    You can specify the width of the gaps between columns using the column-gap property and you can define a rule (line) in the middle of the gap using the column-rule property.

    column-gap

    By default most browsers will use a column gap of 1rem if none is specified. Here's an example with a 5rem column-gap: .col-gap-5rem { column-gap: 5rem; } <article class="col col-gap-5rem col-3"> <p>...</p> <p>...</p> <p>...</p> </article>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede. Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.

    column-rule

    A rule is just a line between two columns that have content. The value for the column-rule is in the same format as values for border properties: .col-fancy-rule { column-rule: 3px dotted hotpink; } <article class="col col-fancy-rule col-3 col-gap-5rem"> <p>...</p> <p>...</p> <p>...</p> </article>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede. Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.

    Column Span

    With the column-span property set to a value of all, you can have elements within a multi-column elements that span the full width and force a row break: .col h3 { column-span: all; border-bottom: 2px solid var(--subtle-green1); } <article class="col col-fancy-rule col-3 col-gap-5rem"> <p>...</p> <h3>Fancy-enough Title</h3> <p>...</p> <p>...</p> </article>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

    Fancy-enough Title

    Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.
    Firefox doesn't support column-span at the time of this writing.

    Column Breaks

    You can control how an element should break between columns with the break-before, break-inside and break-after properties and with values of avoid or avoid-column. Here's a simple example where paragraph elements won't break into multiple columns: .breaks p { break-inside: avoid-column; } <article class="col col-3 breaks"> <p>...</p> <h3>Fancy-enough Title</h3> <p>...</p> <p>...</p> </article>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

    Fancy-enough Title

    Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.
    The same example without the break-inside rule would look like this, where paragraphs can flow to multiple columns:
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

    Fancy-enough Title

    Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.

    Column Fill

    column-fill controls how the content will be distributed between columns. The initial value, balance, indicates to the browser that the content should be distributed evenly between the columns. First, here's an example where we set a hard-coded height on the multi-column container and where the content is distributed evenly because of the initial value of balance: <article class="col col-3 b30" style="height: 500px;"> <p>...</p> <p>...</p> <p>...</p> </article>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede. Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.
    Now here's the same example, but with column-fill set to auto instead: <article class="col col-3" style="column-fill: auto; height: 500px;"> <p>...</p> <p>...</p> <p>...</p> </article>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede. Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis. Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.
    Browser Support Can I Use multicolumn? Data on support for the multicolumn feature across the major browsers from caniuse.com.

    Implementing A Pure CSS Collapsible

    Collapsible widgets are a popular way to create sections of content that can contract and expand. There are a ton of different implementations out there. Here, thanks to checkbox input elements, label elements and the :checked pseudo-selector, we'll be able create such widget without the need for extra JavaScript.

    Here's what our collapsible looks like:

    QUnit is by calling one of the object that are embedded in JavaScript, and faster JavaScript program could also used with its elegant, well documented, and functional programming using JS, HTML pages Modernizr is a popular browsers without plug-ins. Test-Driven Development. And here's the HTML markup for it: <div class="wrap-collabsible"> <input class="toggle" type="checkbox"> <label for="collapsible" class="lbl-toggle">More Info</label> <div class="collapsible-content"> <div class="content-inner"> <p> QUnit is by calling one of the object that are embedded in JavaScript, and faster JavaScript program could also used with its elegant, well documented, and functional programming using JS, HTML pages Modernizr is a popular browsers without plug-ins. Test-Driven Development. </p> </div> </div> </div> If you want a collapsible to be opened by default, simply set the checked attribute on the checkbox: <input class="toggle" type="checkbox" checked> Bacon ipsum dolor amet pork belly capicola ground round brisket. Shank pork belly cupim fatback. Flank porchetta chicken spare ribs. Ham prosciutto pork belly turkey beef picanha strip steak swine alcatra. Note that each label should be associated with the correct checkbox, so each checkbox element needs a unique id and each label's for attribute should point to the corresponding checkbox's id.

    Styling Our Collapsible

    Let's breakdown the styles bit by bit… First we set the checkbox element to display: none. The checkbox will be invisible and its label will be used instead to check or uncheck it. Later, you'll see that we'll use the CSS :checked pseudo-selector to style things differently when the hidden checkbox is checked: input[type='checkbox'] { display: none; } Next, we style our default label. Here nothing really special is going on, except for the fact that we make our label display as a block element with display: block: .lbl-toggle { display: block; font-weight: bold; font-family: monospace; font-size: 1.2rem; text-transform: uppercase; text-align: center; padding: 1rem; color: #A77B0E; background: #FAE042; cursor: pointer; border-radius: 7px; transition: all 0.25s ease-out; } .lbl-toggle:hover { color: #7C5A0B; } For the small arrow, some clever use of borders makes it easy to create the triangle shape: .lbl-toggle::before { content: ' '; display: inline-block; border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-left: 5px solid currentColor; vertical-align: middle; margin-right: .7rem; transform: translateY(-2px); transition: transform .2s ease-out; } Refer to this post from CSS-Tricks for all your CSS triangle needs. You may have noticed also that we made use of the currentColor built-in variable so that our triangle is the same color as our label's text.
    Let's also give some basic styles to the inner content: .collapsible-content .content-inner { background: rgba(250, 224, 66, .2); border-bottom: 1px solid rgba(250, 224, 66, .45); border-bottom-left-radius: 7px; border-bottom-right-radius: 7px; padding: .5rem 1rem; }
    Now we can start with the interesting part. By default, the collapsible-content div will have a max-height value of 0px, making it completely hidden: .collapsible-content { max-height: 0px; overflow: hidden; transition: max-height .25s ease-in-out; } When a collapsible's checkbox gets checked behind the scenes by clicking its label, we'll set the content div to a high-enough max-height value so that it can grow to display all its internal content. Instead of trying to figure out a good height manually, you can also just make use of viewport units with something like 100vh. Using something like 100% would also work, but you'd lose the ability to use transitions. Note that you'll still probably want to using something like 100% if you think the content in the collapsible could be taller than the viewport. We make use of the adjacent sibling selector (+) to select our content div when the checkbox is checked: .toggle:checked + .lbl-toggle + .collapsible-content { max-height: 100vh; } We use max-height instead of height because we want to avoid using a hard-coded height and want to be able to place content of arbitrary height into our collapsibles. And now we do something really similar using the adjacent sibling selector to rotate our little triangle shape when the collapsible is expanded and to adjust the bottom right and border left radius of our label: .toggle:checked + .lbl-toggle::before { transform: rotate(90deg) translateX(-3px); } .toggle:checked + .lbl-toggle { border-bottom-right-radius: 0; border-bottom-left-radius: 0; } And there you have it! A pretty straightforward way to create a collapsible section without using any scripting at all.

    A Note on Accessibility

    As it is now, our collapsible widget is not really accessible. We'll have to add a touch of JavaScript to make it accessible. I know, I know, the whole thing is supposed to be implemented using zero JavaScript. What can I say! Note that I'm not an accessibility expert, so the following may not be the best way to go about it. Feel free to get in touch if you have a better way. In the following script we select all the toggle labels and listen for keydown events. If the pressed key is either the enter or the spacebar keys, we trigger a click on the label. let myLabels = document.querySelectorAll('.lbl-toggle'); Array.from(myLabels).forEach(label => { label.addEventListener('keydown', e => { // 32 === spacebar // 13 === enter if (e.which === 32 || e.which === 13) { e.preventDefault(); label.click(); }; }); }); To make the label focusable, we add tabindex="0" to it: <label for="collapsible3" class="lbl-toggle" tabindex="0">With A11y</label> Careen fluke jolly boat keel topgallant Admiral of the Black barkadeer sloop poop deck salmagundi. Avast red ensign parley clap of thunder no prey, no pay killick stern clipper execution dock splice the main brace. Grog blossom yardarm bilge water marooned cog wherry tackle aye Shiver me timbers come about.

    All Styles

    Here are the full set styles at once, for your reference: .wrap-collabsible { margin-bottom: 1.2rem 0; } input[type='checkbox'] { display: none; } .lbl-toggle { display: block; font-weight: bold; font-family: monospace; font-size: 1.2rem; text-transform: uppercase; text-align: center; padding: 1rem; color: #A77B0E; background: #FAE042; cursor: pointer; border-radius: 7px; transition: all 0.25s ease-out; } .lbl-toggle:hover { color: #7C5A0B; } .lbl-toggle::before { content: ' '; display: inline-block; border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-left: 5px solid currentColor; vertical-align: middle; margin-right: .7rem; transform: translateY(-2px); transition: transform .2s ease-out; } .toggle:checked + .lbl-toggle::before { transform: rotate(90deg) translateX(-3px); } .collapsible-content { max-height: 0px; overflow: hidden; transition: max-height .25s ease-in-out; } .toggle:checked + .lbl-toggle + .collapsible-content { max-height: 100vh; } .toggle:checked + .lbl-toggle { border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .collapsible-content .content-inner { background: rgba(250, 224, 66, .2); border-bottom: 1px solid rgba(250, 224, 66, .45); border-bottom-left-radius: 7px; border-bottom-right-radius: 7px; padding: .5rem 1rem; } Enjoy your fancy almost-CSS-only collapsible!

    Defining Custom Fonts in CSS With @font-face and font-display

    @font-face is the CSS at-rule to use to define custom fonts to be made available to your web pages. With @font-face, you provide a path to a font file that's on the same domain as your CSS file, so this mean that the rule should be used with fonts that are hosted on your servers. The rule has been around for quite some time, but a rather new property, font-display, brings a new level of loading options, which we'll go over.

    Basic Usage

    Your @font-face at-rules should be defined first in your main CSS file and the most basic version of the rule should have the font-family and src properties. Here's an example: @font-face { font-family: Lato; src: url(/assets/fonts/Lato.woff2) format('woff2'), url(/assets/fonts/Lato.woff) format('woff'); } The value for font-family will be the name used when you later use the font on your page: h1 { font-family: Lato, sans-serif; }
    Notice how, for src, we provided two values. The first is for the font in the more modern woff2 format. Support for it is still lacking in some browsers, so we also provided a fallback in woff format, which has support all the way back to Internet Explorer 9. That should cover your needs, but you can provide even more fallbacks if you wish: @font-face { font-family: Lato; src: url(/assets/fonts/Lato.woff2) format('woff2'), url(/assets/fonts/Lato.woff) format('woff'), url(/assets/fonts/Lato.ttf) format('truetype'); }

    Local version

    If you're using a font that you suspect a lot of users would already have installed on their device, you can also provide a local value to lookup first: @font-face { font-family: Lato; src: local("Lato"), url(/assets/fonts/Lato.woff2) format('woff2'), url(/assets/fonts/Lato.woff) format('woff'); } Note that there can be issues with loading a local version of a font. See this explanation by Paul Irish to learn more.

    Style Linking

    On top of defining the font name and its path, you can also define specific properties for the font. The properties that you can set are font-style, font-variant, font-weight & font-stretch. This is helpful especially to use multiple variations of a font under the same name. For example: @font-face { font-family: Lato; src: local("Lato"), url(/assets/fonts/Lato.woff2) format('woff2'), url(/assets/fonts/Lato.woff) format('woff'); } @font-face { font-family: Lato; src: url(/assets/fonts/Lato-LightItalic.woff2) format('woff2'), url(/assets/fonts/Lato-LightItalic.woff) format('woff'); font-weight: 200; font-style: italic; } With this, if you can do something like the following example to use the Light Italic version of your font for h1 elements and the regular version for p elements: h1, p { font-family: Lato, sans-serif; } h1 { font-weight: 200; font-style: italic; }

    Controlling Font Loading: Enter font-display

    @font-face is not new, but font-display is a new property that can be used with @font-face that gives us more control with how a font is loaded. It's common when using custom fonts to be faced with either a FOUT (flash of unstyled text) or a FOIT (flash of invisible text) when a page is first loaded. Some browsers choose to show the text right away even if the custom font is not loaded and then revert to the custom font when its fully loaded, but this creates a FOUT. Still other browsers will have the text hidden for a short period of time to give time for the custom font to load. If the font doesn't load during the window of time, then the fallback is used. One way to deal with FOUT is to use a tool like Font Style Matcher to find a fallback font that's as close to the custom font as possible, so that the font change doesn't feel so drastic. With font-display, we can control exactly how we want the font to be loaded: @font-face { font-family: Lato; src: url(/assets/fonts/Lato-LightItalic.woff2) format('woff2'), url(/assets/fonts/Lato-LightItalic.woff) format('woff'); font-weight: 200; font-style: italic; font-display: swap; }
    font-display can take one of 5 values:
  • auto: The default behavior, which can be different depending on the browser.
  • block: The text is first hidden for a short period, and can then change to the custom font whenever its available. This one is know as having an infinite swap period.
  • swap: The text is never hidden and changes to the custom font when its available. This also gives for an infinite swap period.
  • fallback: With fallback, the text is hidden for a very short period (the block period), then there's a short swap period. If the custom font doesn't make it during the swap period, then it's not loaded at all.
  • optional: The new kid on the block, and possibly a good solution for all our font loading problems. With font-display: optional, there's a window of only about 100ms for the custom font to load (the block period). If the font doesn't load during that block period, the fallback font is used and the custom font is not loaded at all, but it's still downloaded and cached behind the scenes. This means that, on subsequent page loads, the custom font should be available in the cache and will load instantly.

  • font-display: optional is what's used on this website for titles. On the first page visit, users see a fallback that uses a system font, then upon visiting more pages, the custom Lato Light Italic is used instead: @font-face { font-family: Lato; src: url(/assets/fonts/Lato-LightItalic.woff2) format('woff2'), url(/assets/fonts/Lato-LightItalic.woff) format('woff'); font-display: optional; } h1 { font-family: Lato, "Segoe UI", "Helvetica Neue", Helvetica, Roboto, 'Open Sans', FreeSans, sans-serif; font-style: italic; font-weight: 200; } The one downside right now is that support for font-display is still very limited. Browser Support Can I Use css-font-rendering-controls? Data on support for the css-font-rendering-controls feature across the major browsers from caniuse.com.

    Getting Fancy With Text Decoration in CSS

    They say good things come to those who wait, and this turns out to be very true when it comes to text decoration on the web. The CSS Text Decoration Module Level 3 defines a few great new ways to decorate text on the web, and browsers are finally starting to have good support for them. The times of using border-bottom instead of a proper text underline in order to get a different underline color may finally come to pass. Results may vary: support is still limited, so the examples in this post may not display correctly depending on the browser you're using.

    text-decoration

    The text-decoration property used to be only about a choice between values of none, underline, overline and line-through, but with the new recommendation is becomes a shorthand for the new text-decoration-color, text-decoration-style and text-decoration-line properties. For example, here's a colored double underline: .fancy { -webkit-text-decoration: hotpink double underline; text-decoration: hotpink double underline; } Fancy Underline

    text-decoration-color

    Works just as you would imagine. Finally a way to change the text decoration color!

    text-decoration-style

    text-decoration-style is used to define the type of text decoration, and the new recommendation brings two new values: double and wavy: .wavy { text-decoration: underline; -webkit-text-decoration-color: salmon; text-decoration-color: salmon; -webkit-text-decoration-style: wavy; text-decoration-style: wavy; } Wavy Decoration

    text-decoration-line

    text-decoration-line accepts values of underline, overline, line-through and blink (blink is deprecated however): .strike { -webkit-text-decoration-color: red; text-decoration-color: red; -webkit-text-decoration-line: line-through; text-decoration-line: line-through; } Strike This

    text-decoration-skip

    With text-decoration-skip we can avoid having the decoration step over parts of the element its applied to. The possible values are objects, spaces, ink, edges and box-decoration.
  • ink: Finally, a way to prevent text decoration from overlapping glyph descenders:
  • .ink { -webkit-text-decoration: darkturquoise solid underline; text-decoration: darkturquoise solid underline; -webkit-text-decoration-skip: ink; text-decoration-skip: ink; } Hippopotamus
  • objects: The text decoration skips elements that have a display of inline-block. It's also the initial value:
  • <p class="super"> Getting <span style="display: inline-block;">Very</span> Fancy </p> .super { -webkit-text-decoration: peru solid overline; text-decoration: peru solid overline; -webkit-text-decoration-skip: objects; text-decoration-skip: objects; } Getting Very Fancy
    The remaining values are not yet well supported by browsers:
  • spaces: The decoration skips spaces and punctuation.
  • edges: Creates a gap when two elements with text decoration are next to each other.
  • box-decoration: The decoration skips any inherited margin, padding or border.
  • text-underline-position

    With text-underline-position we have yet another way to control the positioning of text decoration in relation to the glyphs. The possible values are auto, under, left and right. With auto, the initial value, browsers will usually place the decoration close to the text baseline: .auto { -webkit-text-decoration: slateblue solid underline; text-decoration: slateblue solid underline; -webkit-text-underline-position: auto; text-underline-position: auto; } Hippopotamus …and notice now how, with under, the decoration is placed after the text descenders: .under { -webkit-text-decoration: slateblue solid underline; text-decoration: slateblue solid underline; -webkit-text-underline-position: under; text-underline-position: under; } Hippopotamus The left and right values for text-underline-position are used to control text decoration in vertical writing modes. Now go on and impress us with some fancy text decoration! Browser Support Can I Use text-decoration? Data on support for the text-decoration feature across the major browsers from caniuse.com.

    Magazine-Style Shapes Around Floated Elements in CSS With shape-outside

    Part of CSS Shapes module 1, shape-outside is an interesting property that makes it easy to set a shape for the wrapping of text around a floated element. For example, if a floated element is an image with a lot of white-space or if it has a different border radius, the value of shape-outside comes into play to define how text around it will wrap. Using shape-outside allows to create page layouts that approach those that we're used to see in magazines. It can be a nice progressive enhancement for supporting browsers and in non-supporting browsers the property is simply ignored. The value for shape-outside can be a keyword, a shape function or an URL to an image. Let's explore each option briefly:

    Keywords

    You can set shape-outside to a value like margin-box, padding-box, content-box or border-box. This makes it easy to have text that follows the border radius value applied to the floated element: Shape outside margin-box Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque faucibus euismod tempor. Ut ac condimentum neque. Vivamus vel tristique lacus. Aenean volutpat volutpat diam, eu volutpat mauris. Donec interdum tempor risus. Maecenas eu tincidunt tortor. Donec tincidunt turpis enim, ac bibendum lorem blandit at. Pellentesque ullamcorper ex sit amet mauris dictum varius. img.shape1 { float: left; margin-right: 2rem; border-radius: 0% 90%; -webkit-shape-outside: margin-box; shape-outside: margin-box; }

    Shape Functions

    shape-outside can also take one of four possible shape functions: circle(), polygon(), ellipse() or inset().

    Circle

    Here's an example with an image that's floated to the left and that has a border-radius of 50%: Shape outside circle Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non arcu nec lacus venenatis pulvinar. Cras lacinia turpis diam, at euismod velit auctor sed. Curabitur bibendum sodales tortor et lobortis. Cras vitae vulputate ex. Vivamus in faucibus mi. Aliquam auctor sem ac lobortis volutpat. Integer fringilla lacus suscipit nisl blandit, sed efficitur elit ultricies. Curabitur ac laoreet ligula. Nullam et enim ut risus commodo tempor. Vivamus dictum sit amet erat vitae dapibus. img.shape2 { float: left; margin-right: 2rem; border-radius: 50%; -webkit-shape-outside: circle(); shape-outside: circle(); } The circle() shape function can also take a radius and a position value: /* Circle width a 40% radius and positioned at 20% 60% */ shape-outside: circle(40% at 20% 60%);

    Ellipse

    In the case of the ellipse() shape function, the syntax is similar to circle's, except that a X-radius and Y-radius is provided: Shape outside ellipse Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quam dolor, pulvinar et odio eu, accumsan malesuada augue. Donec luctus et neque nec dignissim. Phasellus varius ex sit amet ipsum gravida, at tincidunt neque luctus. Proin molestie, risus eu interdum bibendum, mauris urna laoreet nisi, in eleifend eros arcu in elit. Donec imperdiet dignissim erat et semper. Maecenas vestibulum tempor neque id pellentesque. Aenean vel justo maximus metus rutrum accumsan ac a dolor. Vivamus a nunc non elit luctus ornare pretium id risus. Nunc diam sapien, varius sit amet accumsan sit amet, malesuada quis diam. Donec condimentum odio eu ex pretium facilisis. Phasellus ligula enim, pulvinar sit amet efficitur vitae, sodales at elit. Donec sagittis arcu in convallis molestie. Maecenas vehicula hendrerit lacus at ornare. Suspendisse mattis ac mauris eu auctor. Nulla eu ipsum a lectus posuere aliquam id id est. .shape3 { float: right; width: 230px; height: 140px; margin-left: 2rem; border-radius: 50%; -webkit-shape-outside: ellipse(100px 55px at 38.7% 52.25%); shape-outside: ellipse(100px 55px at 38.7% 52.25%); object-fit: cover; } Here we also used object-fit to ensure that the image keeps its aspect ratio even though we squished the dimensions.

    Polygon

    You can create all kinds of interesting shapes using the polygon() color function. It's quite complicated to figure out the proper dimmensions however, so for more complex shapes you'll probably want to use a tool like this great CSS Shapes Editor Chrome Extension. Shape outside polygon Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quam dolor, pulvinar et odio eu, accumsan malesuada augue. Donec luctus et neque nec dignissim. Phasellus varius ex sit amet ipsum gravida, at tincidunt neque luctus. Proin molestie, risus eu interdum bibendum, mauris urna laoreet nisi, in eleifend eros arcu in elit. Donec imperdiet dignissim erat et semper. Maecenas vestibulum tempor neque id pellentesque. Aenean vel justo maximus metus rutrum accumsan ac a dolor. Vivamus a nunc non elit luctus ornare pretium id risus. Nunc diam sapien, varius sit amet accumsan sit amet, malesuada quis diam. Donec condimentum odio eu ex pretium facilisis. Phasellus ligula enim, pulvinar sit amet efficitur vitae, sodales at elit. Donec sagittis arcu in convallis molestie. Maecenas vehicula hendrerit lacus at ornare. Suspendisse mattis ac mauris eu auctor. Nulla eu ipsum a lectus posuere aliquam id id est. img.shape4 { float: left; -webkit-shape-outside: polygon(-5px 86px, 243px 253px, 300px 220px, 296px 434px, -2px 434px); shape-outside: polygon(-5px 86px, 243px 253px, 300px 220px, 296px 434px, -2px 434px); -webkit-shape-margin: .7rem; shape-margin: .7rem; } Here notice the use of the shape-margin property, to nudge the whole shape slightly.

    Inset

    With the inset() shape function, you proved inset values for the top, right, bottom and left positions: Shape outside inset Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quam dolor, pulvinar et odio eu, accumsan malesuada augue. Donec luctus et neque nec dignissim. Phasellus varius ex sit amet ipsum gravida, at tincidunt neque luctus. Proin molestie, risus eu interdum bibendum, mauris urna laoreet nisi, in eleifend eros arcu in elit. Donec imperdiet dignissim erat et semper. Maecenas vestibulum tempor neque id pellentesque. Aenean vel justo maximus metus rutrum accumsan ac a dolor. Vivamus a nunc non elit luctus ornare pretium id risus. Nunc diam sapien, varius sit amet accumsan sit amet, malesuada quis diam. Donec condimentum odio eu ex pretium facilisis. Phasellus ligula enim, pulvinar sit amet efficitur vitae, sodales at elit. Donec sagittis arcu in convallis molestie. Maecenas vehicula hendrerit lacus at ornare. Suspendisse mattis ac mauris eu auctor. Nulla eu ipsum a lectus posuere aliquam id id est. img.shape5 { float: right; -webkit-shape-outside: inset(50px 0 50px 55px); shape-outside: inset(50px 0 50px 55px); }

    URL

    We can provide an image via an URL, and the opaque parts of the image with create the shape: Shape outside URL Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quam dolor, pulvinar et odio eu, accumsan malesuada augue. Donec luctus et neque nec dignissim. Phasellus varius ex sit amet ipsum gravida, at tincidunt neque luctus. Proin molestie, risus eu interdum bibendum, mauris urna laoreet nisi, in eleifend eros arcu in elit. Donec imperdiet dignissim erat et semper. Maecenas vestibulum tempor neque id pellentesque. Aenean vel justo maximus metus rutrum accumsan ac a dolor. Vivamus a nunc non elit luctus ornare pretium id risus. Nunc diam sapien, varius sit amet accumsan sit amet, malesuada quis diam. Donec condimentum odio eu ex pretium facilisis. Phasellus ligula enim, pulvinar sit amet efficitur vitae, sodales at elit. Donec sagittis arcu in convallis molestie. Maecenas vehicula hendrerit lacus at ornare. Suspendisse mattis ac mauris eu auctor. Nulla eu ipsum a lectus posuere aliquam id id est. img.shape6 { float: left; shape-outside: url("/shape.png"); } Here's what our transparent png (shape.png) image looks like: Shape image
    Browser Support Can I Use css-shapes? Data on support for the css-shapes feature across the major browsers from caniuse.com.

    Masking Images in CSS Using the mask-image Property

    We covered the use of the clip-path property for clipping using CSS, so it's only natural that we now go over masking. Contrary to clipping, where a part of an image or element is either completely invisible or completely visible, with masking we can hide or show parts of an image with different levels of opacity. Masking in CSS is done using the mask-image property, and an image has to be provided as the mask. Anything that's 100% black in the image mask with be completely visible, anything that's 100% transparent will be completely hidden, and anything in-between will partially mask the image. Linear and radial gradients in CSS are generated images, so they can be used as the image mask. SVGs that use the mask element can also be used as the image mask. Let's go over the 3 possibilities for image masks with concrete examples:

    Masking Using Gradients

    Let's first use a simple linear gradient that goes from transparent to black. The first image is our default starting image, and the second image has our linear gradient applied as the mask-image value: Without maskWith gradient mask Here's the CSS rules used here: .mask1 { -webkit-mask-image: linear-gradient(to bottom, transparent 25%, black 75%); mask-image: linear-gradient(to bottom, transparent 25%, black 75%); } Here are two more examples of interesting effects that can be accomplished with masking using gradients: Gradient mask example 2Gradient mask example 3 And the CSS rules for these 2 gradient masks: .mask2 { -webkit-mask-image: radial-gradient(circle at 50% 60%, black 50%, rgba(0, 0, 0, 0.6) 50%); mask-image: radial-gradient(circle at 50% 60%, black 50%, rgba(0, 0, 0, 0.6) 50%); } .mask3 { -webkit-mask-image: radial-gradient(ellipse 90% 80% at 48% 78%, black 40%, transparent 50%); mask-image: radial-gradient(ellipse 90% 80% at 48% 78%, black 40%, transparent 50%); }

    Masking Using Images

    Here's we're using an image that was created using Sketch as our image mask. The first image is the image mask itself, and the second image has that mask applied to it: Image maskWith image mask And our CSS looks like this: .mask4 { -webkit-mask-image: url("/path/to/image-mask.png"); mask-image: url("/path/to/image-mask.png"); -webkit-mask-size: 400px 600px; mask-size: 400px 600px; } We specified a value for mask-size here because our image mask is 800px by 1200px, but here we want everything shrunk by half so that the image can look sharp on retina displays.

    Masking Using SVG Masks

    Finally, if SVG is your groove, you can define image masks using the SVG mask element. The first example currently only seems to be working in Firefox (you probably won't see anything in non-supporting browsers). It defines the SVG mask and then we reference the ID of the mask in CSS as usual. The second example seems to have wider support and defines the image as part of the SVG element itself. Also note that with SVG masks, the colors to use are white and black instead of transparent and black. The colors also work in reverse and white/partially white is what will be visible. With SVG mask

    Example 1 (triangle)

    Here's the SVG markup for the first example: <svg width="0" height="0" viewBox="0 0 400 600"> <defs> <mask> <rect fill="#000000" x="0" y="0" width="400" height="600"></rect> <polygon fill="#FFFFFF" points="200.5 152 349 449 52 449"></polygon> </mask> </defs> </svg> Then we can apply the mask to our image with mask-image as usual by refecencing the ID of the SVG mask: .mask5 { -webkit-mask-image: url(#my-svg-mask); mask-image: url(#my-svg-mask); }

    Example 2 (bubbles)

    For our second SVG example, everything is contained in the SVG definition, including our main image itself: <svg width="400px" height="600px" viewBox="0 0 400 600"> <defs> <mask> <rect fill="#000000" x="0" y="0" width="400" height="600"></rect> <circle fill="#FFFFFF" cx="67.5" cy="51.5" r="67.5"></circle> <circle fill="#FFFFFF" cx="296.597656" cy="118.597656" r="56.5976562"></circle> <circle fill="#FFFFFF" cx="53.4648437" cy="256.464844" r="81.4648437"></circle> <circle fill="#FFFFFF" cx="239.587891" cy="313.587891" r="70.5878906"></circle> <circle fill="#FFFFFF" cx="366.597656" cy="562.597656" r="56.5976562"></circle> <circle fill="#FFFFFF" cx="93.203125" cy="486.203125" r="76.203125"></circle> </mask> </defs> <image mask="url(#my-svg-mask2)" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/images/css/masking/masking-example1.jpg" width="400" height="600"></image> </svg>
    Browser Support Can I Use css-masks? Data on support for the css-masks feature across the major browsers from caniuse.com.

    Apply Filters to Background Elements in CSS With backdrop-filter

    New in the CSS filter effects module 2 is the backdrop-filter property. It allows to set filters similar to the ones we're used to (saturation, blur, hue-rotate,…), but for elements in the background. Coupled with the fact that it's an animatable property, it allows for some very fun UI effects. Support for backdrop-filter is still very limited, so the example in this post may not display properly for you. For now, you can try in Safari, in Chrome with the Experimental Web Platform Features enabled or in Chrome Canary The easiest way to understand backdrop-filter is with a concrete example. Let's first create a fun little ice cream widget like this: Ice Cream Please
  • Chocolate
  • Straberry
  • Chocolate Straberry
  • Pineapple
  • Cookie dough
  • Background image

    Here's our markup:

    <div class="backdrop-example"> <div class="foreground"> <div class="ice-cream"> <span> Ice Cream Please &#8675;</span> <ul> <li> Chocolate</li> <li> Straberry</li> <li> Chocolate Straberry</li> <li> Pineapple</li> <li> Cookie dough</li> </ul> </div> </div> <div class="background"> <img src="/path/to/ice-cream.jpg" width="500" height="655" alt="Ice Cream!"> </div> </div>

    And here are our basic styles:

    .backdrop-example { position: relative; width: 500px; max-width: 100%; margin: 0 auto; } .foreground { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.3); position: absolute; } .foreground .ice-cream { color: saddlebrown; display: inline-block; background: rgba(255,255,255,0.8); padding: .75rem 2rem; box-shadow: 0 0 10px rgba(0,0,0,0.05); border-radius: 7px; cursor: pointer; transition: transform .15s ease-out; } .foreground .ice-cream:hover { transform: scale(1.04); } .foreground ul { max-height: 0; margin: 0; overflow-y: hidden; } .foreground.active ul { max-height: 700px; transition: max-height .4s ease-out; } .foreground li { padding: 0.7rem 0; margin: 0; font-size: .9rem; transition: background-color .2s; } .foreground li:hover { background-color: rgba(255, 255, 255, .9); } We use a starting max-height of 0 and then transition to a high enough max-height to toggle our ice cream flavors.

    Finally, a tiny amount of JavaScript to toggle the active class

    let foreground = document.querySelector('.foreground'); let trigger = document.querySelector('.ice-cream'); trigger.addEventListener('click', function() { foreground.classList.toggle('active'); });

    Adding backdrop-filter

    Now for the fun part, let's add rules to give a slight blur and desaturate the background when the ice cream flavors are toggled open: .foreground { /* ... */ transition: backdrop-filter 1.5s ease-out; } .foreground.active { -webkit-backdrop-filter: blur(4px) saturate(20%); backdrop-filter: blur(4px) saturate(20%); }

    ...and the final result:

    Ice Cream Please
  • Chocolate
  • Straberry
  • Chocolate Straberry
  • Pineapple
  • Cookie dough
  • Background image
    Thanks to ian dooley for the cool ice cream photo!
    Browser Support Can I Use css-backdrop-filter? Data on support for the css-backdrop-filter feature across the major browsers from caniuse.com.

    The CSS :focus-within Pseudo-Class

    Selecting a parent element has long been impossible to do using just CSS, but a new pseudo-class, :focus-within, changes that story somewhat. It allows to style an element when it has focus, but also when any of its inner elements (descendants) have focus. A prime example is with a form where you'd want a container element to be styled a certain way when the user focuses into one of the input elements. Here's an example of using :focus-within with a form. Let's start with this markup: <form tabindex="0" class="myForm"> <h3>Please fill my form </h3> <input type="text" placeholder="Your animal name"> <input type="text" placeholder="Your favorite place in the world"> </form> And our CSS rules are the following: .myForm:focus-within { background: #f8f8f8 repeating-linear-gradient( 45deg, transparent, transparent 35px, rgba(255, 255, 255, 0.5) 35px, rgba(255, 255, 255, 0.5) 70px ); } .myForm:focus-within::before { content: "I'm a happy selected form!"; color: rgb(239, 187, 53); }
    Below you can see the result if you're using a supporting browser. Notice how the different background is applied to the containing form element when the form itself is focused or when either of the inputs are focused. If we had used the good old :focus pseudo-class instead of :focus-within, our container form would be styled only when the focus is on the form itself, but not when the inputs are focused:

    Please fill my form


    In order for :focus-within to work as expected, you'll have to make sure that the inner elements of the container are focusable. Input elements are focusable by default, but div, img or p elements, for example, are not. The tabindex attribute can be used to make an element focusable. The container element should also be focusable in order to receive the styling when focusing from just the container. Thanks to Lea Verou for the CSS background pattern. Browser Support Can I Use css-focus-within? Data on support for the css-focus-within feature across the major browsers from caniuse.com.

    Minimal CSS Reset

    Your CSS reset rules don't have to be a mile long, and most modern browsers are now pretty uniform with their base layout. Below you'll find what I judge to be a good minimal effective dose for a reset. Just copy it in your new projects and you'll be up and running. Bookmark this page for a quick & easy reference

    Here's the CSS reset:

    html { box-sizing: border-box; font-size: 16px; } *, *:before, *:after { box-sizing: inherit; } body, h1, h3, h3, h4, h5, h6, p, ol, ul { margin: 0; padding: 0; font-weight: normal; } ol, ul { list-style: none; } img { max-width: 100%; height: auto; }

    A few things to note

  • As you can see, I've included a rule so that images are responsive by default.
  • Arguably the most important part of this CSS reset is the box-sizing: border-box, as this will ensure consistent and predictable sizing. The default value of content-box doesn't account for the padding or border.
  • You can remove the rule for ol and ul if you want to keep the default bullet points for your lists.
  • With font-weight: normal headings won't be bolded by default. Remove that if you don't mind the default look.
  • I've set the default font size to be 16px. Everything else can be specified in rem units and it will be based off of that 16px. Then, if you want to adjust globally to make the text a little larger overall, you can change the base rule for something like 17 or 18px.
  • Think something is missing? Get in touch here to let us know!

    Exploring Blend Modes in CSS

    Two properties allow us to blend colors together in CSS: mix-blend-mode and background-blend-mode. With mix-blend-mode, we define the blending between the element and the element(s) that are behind it. With background-blend-mode, we define the blending between the element's background image and its background color. The available blend mode values for both properties are the following 16:
  • color
  • color-burn
  • color-dodge
  • darken
  • difference
  • exclusion
  • hard-light
  • hue
  • lighten
  • luminosity
  • multiply
  • normal
  • overlay
  • saturation
  • screen
  • soft-light
  • You'll find that the most useful blend modes for pleasing results are darken, multiply, overlay, screen and soft-light.

    mix-blend-mode

    Let's use the following two images: Foreground imageBackground image Now let's see what can be done with the mix-blend-mode property, with the in the foreground and using a soft-light blend mode: Foreground imageBackground image Here's the markup: <div class="blend1"> <img src="https://alligator.io/css//images/css/blend-modes/monkey.jpg" width="400" height="600"> <img src="https://alligator.io/css//images/css/blend-modes/sky.jpg" width="400" height="600"> </div> And the applying the blend mode is as simple as it gets: .blend1 img:first-child { position: absolute; mix-blend-mode: soft-light; }

    Try it Yourself!

    See the effect of the different blend modes in action here: Try the different blend modes Here are the two blended images:

    background-blend-mode

    For our background-blend-mode example, let's use this dark image, a background color of salmon and a blend mode of screen: Example image for background-blend-mode  For our blending to work, the image is used as the background for a div element: .blend2 { width: 400px; height: 534px; max-width: 100%; background-blend-mode: screen; background-image: url('/images/css/blend-modes/dark.jpg'); background-color: salmon; background-size: cover; }
    background-blend-mode can also blend multiple background images together. Linear and radial gradients are really background images, so an image can therefore be blending with a gradient: Example with linear gradient  Here we used a blend mode of overlay and some a nice light to dark purple linear gradient: .blend3 { width: 400px; height: 600px; max-width: 100%; background-blend-mode: overlay; background-image: url('/images/css/blend-modes/parrot.jpg'), linear-gradient(to bottom, #efe8f5, #8845e0); background-size: cover; } Browser Support Can I Use css-backgroundblendmode? Data on support for the css-backgroundblendmode feature across the major browsers from caniuse.com.

    Styling Form Inputs in CSS With :required, :optional, :valid and invalid

    When it comes to validating the content of input fields on the frontend, things are much easier now than they they used to be. We can use the :required, :optional, :valid and :invalid pseudo-classes coupled with HTML5 form validation attributes like required or pattern to create very visually engaging results. These pseudo-classes work for input, textarea and select elements. Here's a basic example of the pseudo-classes at work. Let's start with this basic markup: <form action="#" class="simple-form"> <input type="text" placeholder="First Name" required> <input type="email" placeholder="Email" required> <input type="text" placeholder="Nick name"> <input type="text" placeholder="Favorite pizza toping"> </form> And let's apply the following styles: .simple-form { display: flex; overflow-y: scroll; padding-bottom: 1.25rem; } .simple-form input { margin: 0 .25rem; min-width: 125px; border: 1px solid #eee; border-left: 3px solid; border-radius: 5px; transition: border-color .5s ease-out; } .simple-form input:optional { border-left-color: #999; } .simple-form input:required { border-left-color: palegreen; } .simple-form input:invalid { border-left-color: salmon; }

    Here's the result:


    Notice how our input of type email requires more than just any text to become valid. That's thanks to modern browsers having a different rule to satisfy the required attribute for email input types.

    Focus Pseudo-Class

    Let's make things even more interesting by also styling according to the focus state and add a small background image depending on the validity state and only when the input is in focus. We'll start with the same form markup. Here's our styles this time: .simple-form { display: flex; overflow-y: scroll; padding-bottom: 1.25rem; } .simple-form input { margin: 0 .25rem; min-width: 125px; border: 1px solid #eee; border-left: 3px solid; border-radius: 5px; transition: border-color .5s ease-out; } .simple-form input:optional { border-left-color: #999; } .simple-form input:required:valid { border-left-color: palegreen; } .simple-form input:invalid { border-left-color: salmon; } .simple-form input:required:focus:valid { background: url("/images/check.svg") no-repeat 95% 50%; background-size: 25px; } .simple-form input:focus:invalid { background: url("/images/tnt.svg") no-repeat 95% 50%; background-size: 45px; }

    And here's the result:


    You could be tempted to add content instead using ::before or ::after on the input, but unfortunately that's not possible on input elements. One trick would be to have a sibling span element that has content added depending on the validity of the input. Something like this:

    input:focus:invalid + span::before { ... }.
    Browser Support Can I Use form-validation? Data on support for the object-fit feature across the major browsers from caniuse.com.

    Cropping Images in CSS With object-fit

    Ever wanted an image to fit exactly into a certain given dimension, but while keeping its aspect ratio and avoid having a squished image? This wasn't something that could easily be done using CSS for the longest time. One trick was to resort to using a background image instead to go around the issue. Well the problem is no more with the object-fit property! Along with inherit, initial and unset, there are 5 more possible values for object-fit:
  • contain: The image keeps its original aspect ratio, but resized so that the longest of either the height or width can fit in the given dimensions.
  • cover: The image keeps its original aspect ratio and the image area is completely covered.
  • fill: The initial value. The image will fill its given area, even if it means losing its aspect ratio.
  • none: The image is not resized at all, and the original image size fills the given area.
  • scale-down: The smaller of either contain or none.
  • Let's demonstrate with an example. The following image's original width is 1200px and height is 674px. Here it's shown at half its size, 600px by 337px: Our starting image Now we have a problem if we need the image to be the same height, but fit in half the width. The original aspect ratio is lost and the result is a squished image: Our image lost its aspect ratio object-fit can fix that issue for us. Let's showcase the different values:

    object-fit: contain

    .alligator-turtle { object-fit: contain; } Our image lost its aspect ratio

    object-fit: cover

    .alligator-turtle { object-fit: cover; } Our image lost its aspect ratio

    object-fit: fill

    .alligator-turtle { object-fit: fill; } Our image lost its aspect ratio

    object-fit: none

    .alligator-turtle { object-fit: none; } Our image lost its aspect ratio

    object-fit: scale-down

    .alligator-turtle { object-fit: scale-down; } Our image lost its aspect ratio In this particular example, object-fit: cover is probably what will work the best for our needs.

    object-position

    Now, say your image was cropped with object-fit, but the part of the image that's shown is not positioned as you'd like. You can use the object-position property to control exactly that. Let's start with our object-fit: cover example: .alligator-turtle { object-fit: cover; width: 300px; height: 337px; } Our image lost its aspect ratio Now let's change the position of the visible part of the image on the X axis so that we see the right-most edge of the image: .alligator-turtle { object-fit: cover; object-position: 100% 0; width: 300px; height: 337px; } Our image lost its aspect ratio And finally, here's what happens if you provide a position that's out of bounds: .alligator-turtle { object-fit: cover; object-position: -20% 0; width: 300px; height: 337px; } Our image lost its aspect ratio Browser Support Can I Use object-fit? Data on support for the object-fit feature across the major browsers from caniuse.com.

    Website Theming With CSS Custom Properties

    You may have noticed that you can now toggle between dark and light themes on the site. This was done using CSS custom properties (aka CSS variables). In this post you'll see how you can achieve something similar using only CSS and a touch of JavaScript. The power of custom properties in CSS really shines here because, unlike with variables defined using a CSS preprocessor, they are dynamic and their values can be changed or overwritten at any point in time and as response to user input. When the value of a variable is changed or overwritten, all elements that use the variable will automatically reflect the change. A CSS variable theming example First you'll have to do a bit of grunt work and extract all the colors that you want to make themable into CSS custom properties. Let's say we're starting with the following styles: body { background: white; color: #555; } a, a:link { color: #639A67; } a:hover { color: #205D67; } You'll then define the custom properties as such: :root { --bg: white; --text-color: #555; --link-color: #639A67; --link-hover: #205D67; } With this in place, your CSS rules can now be changed to something like the following: body { background: var(--bg); color: var(--text-color); } a, a:link { color: var(--link-color); } a:hover { color: var(--link-hover); } Applying the theme will be as simple as adding a class to the body element, so you'll define the theme's colors under that class name. Here we'll call the class funky. Simply make sure to define an override color for all colors should change: .funky { --bg: hotpink; --text-color: white; --link-color: #B793E6; --link-hover: #3532A7; }

    Fallbacks for Older Browsers

    Support for CSS custom properties is pretty good, but you'll most likely want to include fallbacks for users that are on older browsers. Let's say that we have an element that should have a linear-gradient background with colors defined as custom properties. It's as simple as providing hard-coded colors first, and older browsers will ignore the version that they don't understand: background: linear-gradient(to right, #FFFB85, #5A3662); /* our fallback */ background: linear-gradient(to right, var(--top-grad1), var(--top-grad2));

    Toggling Our Theme

    We only need a very minimal amount of JavaScript to add an even listener on a element that acts as the toggle button between the two themes. Here the toggle button has the toggle-theme class and we use document.querySelector to get a reference to that element: let toggle = document.querySelector('.toggle-theme'); toggle.addEventListener('click', function(e) { e.preventDefault(); if (document.body.classList.contains('funky')) { // Turning the theme off: document.body.classList.remove('funky'); // Reverse logic on the button text, so that users can turn // the theme back on: toggle.innerText = ' Turn theme on'; } else { document.body.classList.add('funky'); toggle.innerText = 'Turn theme off'; } }); This does the trick to toggle between the two themes. We can do better however and also add/remove an item to localStorage at the same time so that our theme gets applied automatically when the page loads: let toggle = document.querySelector('.toggle-theme'); // Turn the theme of if the 'funky' key exists in localStorage if (localStorage.getItem('funky')) { document.body.classList.add('funky'); toggle.innerText = 'Turn theme off'; } toggle.addEventListener('click', function(e) { e.preventDefault(); if (document.body.classList.contains('funky')) { document.body.classList.remove('funky'); toggle.innerText = ' Turn theme on'; localStorage.removeItem('funky'); } else { document.body.classList.add('funky'); toggle.innerText = 'Turn theme off'; localStorage.setItem('funky', true); } });

    CSS Grid: Justification and Alignment

    With CSS grid layout, the grid itself within its container as well as grid items can be positioned with the following 6 properties: justify-items, align-items, justify-content, align-content, justify-self and align-self. These properties are part of the CSS box alignment module and they define a standard way to position elements with either flexbox or CSS grid. Most of the alignment properties are applied on the grid container, but some are for grid items, for when you want to specify values that apply only for specific grid items. Let's breakdown these properties and their effect one by one. For the examples to follow, we're using the following markup and CSS rules for our grid: <div class="container"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div> .container { display: grid; border: 2px dashed rgba(114, 186, 94, 0.35); height: 250px; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: auto; background: rgba(114, 186, 94, 0.05); } .item { width: 50%; height: 50%; background: rgba(255, 213, 70, 0.4); border: 2px dashed rgba(236, 198, 48, 0.5); } And here's how our base grid looks like:

    Properties on the Grid Container

    justify-items

    justify-items is used to justify the grid items along the row axis. The possible values are start, end, center and stretch. Here are examples with center and end: .container { /* ... */ justify-items: center; } justify-items: center .container { /* ... */ justify-items: end; } justify-items: end

    align-items

    Similar to justify-items, but aligns the grid items along the column axis: .container { /* ... */ align-items: center; } align-items: center .container { /* ... */ align-items: end; } align-items: end
    For the following justify-content and align-content examples, our base styles differ a bit in order to be able to demonstrate a grid that's smaller than its container: .container { /* ... */ grid-template-columns: 100px 100px 100px; grid-template-rows: 75px; height: 300px; } .item { width: 60px; height: 60px; /* ... */ }

    justify-content

    When the entire grid is smaller than the space for the grid container, use justify-content to justify the grid along the row axis. You can use the following values: start, end, center, stretch, space-around, space-between or space evenly: .container { /* ... */ justify-content: end; } justify-content: end .container { /* ... */ justify-content: space-evenly; } justify-content: space-evenly

    align-content

    Similar to justify-content, but align-content aligns the grid along the column axis: .container { /* ... */ align-content: end; } align-content: end .container { /* ... */ align-content: space-evenly; } align-content: space-evenly

    Properties on the Grid Items

    Both justify-self and align-self are analogous to the equivalent properties available on the container (justify-items and align-items), but they apply on specific items that should be positioned differently than the rest of the grid items.

    justify-self (row axis)

    <div class="container"> <div class="item"></div> <div class="item"></div> <div class="item" style="justify-self: end;"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div> justify-self: end

    align-self (column axis)

    <div class="container"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item" style="align-self: end;"></div> <div class="item"></div> <div class="item"></div> </div> align-self: end

    Say Goodbye to the Clearfix Hack With display: flow-root

    The clearfix hack has been around for a long time now, and patches a problem that can happen with floating elements that are larger than their container. Here's an example of the problem: .box { padding: 1rem; background: rgba(255, 213, 70, 0.1); border-bottom: 2px solid rgba(236, 198, 48, 0.2); } .box img { float: left; } <div class="box"> <img src="https://alligator.io/css//images/pirate.svg" width="150" alt="Pirate!"> Alice was beginning to get very tired of sitting by her sister on the bank... </div> Pirate! Alice was beginning to get very tired of sitting by her sister on the bank...

    Clearfix

    The fix is to set overflow: auto on the container, so a class like this is often created and used on elements that contain floated elements: .clearfix { overflow: auto; } <div class="box clearfix"> <img src="https://alligator.io/css//images/police.svg" width="150" alt="Police!"> Alice was beginning to get very tired of sitting by her sister on the bank... </div> And now everything works as expected: Police! Alice was beginning to get very tired of sitting by her sister on the bank...

    display: flow-root

    With display: flow-root on the container element, a new block formatting context is established for the element with flow layout formatting, and this fixes our overflowing issues without resolving to what is essentially a hack: .box { display: flow-root; padding: 1rem; background: rgba(255, 213, 70, 0.1); border-bottom: 2px solid rgba(236, 198, 48, 0.2); } <div class="box"> <img src="https://alligator.io/css//images/chef.svg" width="150" alt="Chef!"> Alice was beginning to get very tired of sitting by her sister on the bank... </div> Chef! Alice was beginning to get very tired of sitting by her sister on the bank... Browser Support Can I Use flow-root? Data on support for the flow-root feature across the major browsers from caniuse.com.

    CSS Grid: grid-gap

    Instead of creating empty grid tracks or trying to hack things up with margins, grid-gap is a property available on grid containers that makes it easy to create gutters in your CSS Grid layouts. grid-gap itself is a shorthand for grid-row-gap and grid-column-gap, and it's very straightforward to use. Note that you should enable the CSS Grid flag in your browser to see the following examples correctly. Here's an example without any grid gaps: html <div class="container"> <div class="item">A</div> <div class="item">B</div> <div class="item">C</div> <div class="item">D</div> <div class="item">E</div> </div> css .container { display: grid; grid-template-columns: 1fr 1fr 200px; grid-template-rows: auto; } .item { background: hsl(162, 76%, 32%); padding: 1rem; } A B C D E
    Now the same example with a grid gap that's the same for rows and columns. When given only one value, grid-row-gap and grid-column-gap will be the same: .container2 { display: grid; grid-template-columns: 1fr 1fr 200px; grid-template-rows: auto; grid-gap: 1rem; } A B C D E
    And then different grid gaps for rows and columns: .container3 { display: grid; grid-template-columns: 1fr 1fr 200px; grid-template-rows: auto; grid-gap: 2rem 10px; /* equivalent to: grid-row-gap: 2rem; grid-column-gap: 10px; */ } A B C D E
    Keep in mind that with grid gaps, even when two rows or columns are not physically touching anymore, they still share the same grid line. Grid gaps don't add any new grid lines.

    Introduction to PostCSS With cssnext and cssnano

    PostCSS is a new tool that makes it easy to develop JavaScript plugins that transform styles. That opens up a new world of possibility for new plugins that make it easier and easier to work with CSS. The post introduces two of the most popular PostCSS plugins: cssnext and cssnano.
  • cssnext allows you to use the future of CSS today. You can use upcoming features or features that are not supported in all browsers like CSS variables and the CSS color function. cssnext will transform your styles so that they work in all browsers. In other words, cssnext allows you to write your styles with the actual CSS syntax instead of a different pre-processor syntax. cssnext will also automatically add vendor prefixes to your styles, so no need to use prefixes yourself when your write your CSS.
  • To give your an example, let's say we have the following CSS styles: :root { --text: hotpink; --bg-color: #F9EC31; --flex-center: { display: flex; margin: auto; } } .box { background-color: var(--bg-color); color: color(hotpink whiteness(25%)); @apply(--flex-center); } .warn { @apply(--flex-center); } cssnext will transform the styles into this: .box { background-color: #F9EC31; color: rgb(255, 64, 159); display: -webkit-box; display: -ms-flexbox; display: flex; margin: auto; } .warn { display: -webkit-box; display: -ms-flexbox; display: flex; margin: auto; }
  • cssnano minifies and compresses your CSS. It removes whitespace, eliminates duplicate rules, removes outdated vendor prefixes, removes comments and performs a lot of other optimizations.
  • cssnext and cssnano can be configured to work according to your specific needs, but here let's just show how to use the defaults. This should hopefully cover most of your use-cases. We'll also use the PostCSS-CLI in this example, but you can also use PostCSS with Webpack or Grunt if that suits your workflow better.

    Installing PostCSS, the PostCSS-CLI, cssnext & cssnano

    Install PostCSS with the cssnext and cssnano plugins through npm: $ npm install --save-dev postcss postcss-cli postcss-cssnext cssnano Or through Yarn: $ yarn add postcss postcss-cli postcss-cssnext cssnano --dev

    Using the PostCSS-CLI

    You use the PostCSS command line interface by providing the input and output files and the PostCSS plugin(s) to use. Specify the plugins with the –use flag, the output file with the –ouput flag and the input file is simply provided last without any flags: $ postcss --use postcss-cssnext --use cssnano --output styles-out.css styles.css You can also use the PostCSS CLI in watch mode, so that it listens for changes to your input file: $ postcss --use postcss-cssnext --use cssnano --output styles-out.css styles.css --watch You can also specify more fine-grained configuration options in a json configuration file and specify the config file with the –config flag: $ postcss --config postcss-config.json Your config file will look like this: { "use": ["postcss-cssnext", "cssnano"], "input": "styles.css", "output": "styles-out.css" }

    npm Script

    To make your workflow easier, simply setup a postcss script in your project's package.json file: "scripts": { "postcss": "postcss --use postcss-cssnext --use cssnano --output styles-out.css styles.css" } Now all your have to do is run the following command: $ npm run postcss

    The CSS color-mod Function

    We've had color functions in preprocessors like Sass for a while now. This ability to adjust and modify colors should be coming soon to CSS with the CSS Color Module Level 4. We'll be able to apply a number of color adjusters to base colors. This becomes very handy when coupled with CSS variables, because it'll be possible to have our base colors defined as variables, and then apply adjusters where needed. Note that color-mod was previously known as just the color function. The name was recently changed in the spec to color-mod. Here's an example of how the color-mod function is used: .box { // Let's make it a little redder color: color-mod(rgb(147,123,25) red(218)); } Or with an HEX value as the base color: .box { color: color-mod(#937b19 contrast(25%); } Or even with computed properties (CSS variables): :root { --base-color: #937b19; } .box { color: color-mod(var(--base-color) tint(59%)); } The resulting color from the above snippets will be rgb(218, 123, 25). You can use multiple color adjuster in the same color function: .box { color: color-mod(purple lightness(62%) red(218) blue(202) whiteness(25%)); }

    Color Adjusters

    Here's a list of available color adjusters:
  • alpha: A value for the alpha-transparency between 0% and 100%.
  • red, green & blue: A value between 0 and 255. Given a starting color of rgb(140, 254, 255), the starting red value would be 140, so anything higher than 140 increases the amount of red in the color and anything lower than 140 decreases the amount of red in color. Green and blue work the same way, with affecting their respective color.
  • blackness & whiteness: A value between 0% and 100%.
  • contrast: A value between 0% and 100%.
  • saturation: A value between 0% and 100%. 0% is gray.
  • lightness: A value between 0% and 100%. 0% is black, and 100% is white.
  • tint: A value between 0% and 100%.
  • hue: A value between 0 and 360.
  • shade: A value between 0% and 100%. 100% is black.
  • blend: Blend makes it easy to blend a color with another color. Here's an example if it's usage:
  • .box { color: color-mod(hotpink blend(yellow 59%)); }

    Browser Support

    CSS Colors Level 4 is still at the Working Draft stage in the recommendation process, and the color function is not implemented in any browser yet. The good news though is that you can start using it today, thanks to PostCSS and the cssnext plugin. Checkout ColorMe.io, a great tool to help you compose colors with the color function.

    CSS Grid: grid-auto-rows + grid-auto-columns

    grid-auto-rows and grid-auto-columns specify the sizing for grid tracks that are generated automatically. The properties come-in really handy when you want to be able to add items that will spill onto new rows/columns, but want to retain some control over the sizing of the implicitly created rows/columns. Both properties default to a value of auto and they are defined on the grid container (the element with display: grid). Let's take this example where we define 2 columns and 2 rows, but place items on a 3rd column and a 3rd row: .container { grid-template-rows: 1fr 2fr; grid-template-columns: 1fr 100px; grid-auto-rows: 125px; grid-auto-columns: 1fr; } .item-1 { grid-column: 3; } .item-2 { grid-row: 3; } We placed our two items outside of the grid we've defined so the 3rd column and row are auto-generated, but we control their size with grid-auto-rows and grid-auto-columns. You can see the result below with our item-1 occupying a 1fr column and our item-2 occupying a 125px row: Item 1 Item 2

    See also

  • grid-auto-flow
  • CSS Grid: grid-auto-flow

    By default items that spill outside of the defined grid tracks will appear in new, auto-generated rows. That is, unless we set grid-auto-flow to column. grid-auto-flow defaults to row and take the value of column. It's defined on the grid container. Compare these two examples, where the items are placed implicitly. First with the default value of row for grid-auto-flow: .container { display: grid; grid-template-rows: 1fr; grid-template-columns: auto; grid-auto-flow: row; } Item 1 Item 2 Item 3
    Then with column: .container { display: grid; grid-template-rows: 1fr; grid-template-columns: auto; grid-auto-flow: row; } Item 1 Item 2 Item 3
    And in this 3rd example, item-1 and item-2 are place explicitly, but item-3 is still auto-placed into a new column instead of a new row: .container { display: grid; grid-template-rows: 1fr; grid-template-columns: auto; grid-auto-flow: column; } .item-1 { grid-row: 1; grid-column: 1; } .item-2 { grid-row: 2; grid-column: 1; } Item 1 Item 2 Item 3

    The Dense Keyword

    By default, if gaps are created in the grid when placing items, auto-positioned grid items will not fill the gaps, but instead will be added after the last item. We can change that with the dense keyword, which tells the implicit grid algorithm to try and go back and fill the gaps with the auto-placed items, changing the order of items when needed: .container { display: grid; grid-gap: 1rem; grid-auto-flow: column dense; } Or: .container { display: grid; grid-gap: 1rem; grid-auto-flow: row dense; } This can be really useful when creating image galleries where the order of items doesn't matter as much.

    See also

  • grid-auto-rows + grid-auto-columns
  • CSS Grid: Holy Grail Layout

    Holy Grail is a layout pattern that's very common on the web. It consists of a header, a main content area with fixed-width navigation on the left, content in the middle and a fixed-width sidebar on the right and then a footer. Holy Grail has been achieved using variety of methods, probably most notably recently with Flexbox. CSS Grid Layout is yet another method, and it should prove to be the most appropriate and straightforward way when browser support gets better. It was designed especially to easily accomplish full page layouts.

    Live Demo

    You can see this demo in action here if you have a supporting browser. Here are quick instructions on how to enable grid layout in Fixefox and Chrome. Holy Grail Layout Demo

    Markup

    The markup is really simple and the amount of elements needed to create the layout is minimal and semantic: <div class="container"> <header> <!-- Header content --> </header> <nav> <!-- Navigation --> </nav> <main> <!-- Main content --> </main> <aside> <!-- Sidebar / Ads --> </aside> <footer> <!-- Footer content --> </footer> </div>

    The grid

    Using grid areas and the fr unit, here's how we define the grid on the container: .container { display: grid; grid-template-areas: "header header header" "nav content side" "footer footer footer"; grid-template-columns: 200px 1fr 200px; grid-template-rows: auto 1fr auto; grid-gap: 10px; height: 100vh; } Notice the use of height: 100vh (100% viewport height) on the container to extend the grid to at least the full height of the viewport. Our grid's middle row is set to a height of 1fr so that it picks up the extra space when needed.

    Grid items

    The grid items are very simple to place on the grid with the grid-area property: header { grid-area: header; } nav { grid-area: nav; margin-left: 0.5rem; } main { grid-area: content; } aside { grid-area: side; margin-right: 0.5rem; } footer { grid-area: footer; }

    Bonus: Making it Responsive

    It's easy to use media queries and to change just a few properties on the grid container to collapse everything into one column on smaller devices: @media (max-width: 768px) { .container { grid-template-areas: "header" "nav" "content" "side" "footer"; grid-template-columns: 1fr; grid-template-rows: auto /* Header */ minmax(75px, auto) /* Nav */ 1fr /* Content */ minmax(75px, auto) /* Sidebar */ auto; /* Footer */ } nav, aside { margin: 0; } }

    Grid and Flexbox

    Grid is not a replacement for Flexbox and Flexbox is still the right solution for one dimension placement and micro layouts. It's very easy to combine grid and flexbox layouts and they are designed to work well together. We can use flexbox on our header for example to have the elements inside the header container be evenly distributed on the horizontal axis: header { grid-area: header; display: flex; justify-content: space-between; align-items: center; }

    CSS Grid Layout: The Repeat Notation

    Repeat() is a notation that you can use with the grid-template-columns and grid-template-rows properties to make your rules more concise and easier to understand when creating a large amount of columns or rows. For example, let's say we have this deffinition for a grid container: .container { display: grid; grid-gap: 10px 15px; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: 100px auto 20% 100px auto 20px; } We can use the repeat() notation like this instead to simplify: .container { display: grid; grid-gap: 10px 15px; grid-template-columns: repeat(3, 1fr 2fr); grid-template-rows: repeat(2, 100px auto 20%); } The first value passed to repeat() is the number of repetitions and the second value is the grid tracks to repeat.

    Repeat() with named lines

    You can also use repeat with named lines: .container { display: grid; grid-auto-flow: column dense; grid-template-columns: repeat(4, [col] 1fr); grid-template-rows: repeat(5, [row] 150px); } Which is equivalent to the following long-form definition: .container { display: grid; grid-auto-flow: column dense; grid-template-columns: [col] 1fr [col] 1fr [col] 1fr [col] 1fr; grid-template-rows: [row] 150px [row] 150px [row] 150px [row] 150px [row] 150px; }
    Named grid lines at the end of repeat notations end up sharing the same line as the next starting name line. For examples, with this: .container { display: grid; grid-auto-flow: column dense; grid-template-columns: repeat(4, [col-start] 1fr [col-end]); grid-template-rows: repeat(5, [row-start] 150px [row-end]); } We get this equivalent long-form definition: .container { display: grid; grid-auto-flow: column dense; grid-template-columns: [col-start] 1fr [col-end col-start] 1fr [col-end col-start] 1fr [col-end col-start] 1fr [col-end]; grid-template-rows: [row-start] 150px [row-end row-start] 150px [row-end row-start] 150px [row-end row-start] 150px [row-end row-start] 150px [row-end]; }

    See Also

  • The Fr Unit
  • Named Lines
  • CSS Grid Layout: The Minmax Function

    CSS Grid Layout makes it easy to create grid tracks that have a size value between a certain range with the CSS minmax function. Let's say you want a column to be between 200px and 500px and then a 1fr column: .container { display: grid; grid-template-columns: minmax(200px, 500px) 1fr; } The value for min has to be smaller than the value for max. Fr units can't be used for the min value, but they can absolutely be used for the max value. In fact, using a 1fr as the max value will ensure that the track expands and takes up the available space: .container { display: grid; grid-template-columns: minmax(250px, 1fr) 1fr; grid-template-rows: 100px 100px; } Used like that, minmax allows to create grid tracks that flex to the available space, but that don't shrink narrower than a specified size. Here's the resulting grid from the above snippet. If you can resize your browser, you'll notice how the 1st column doesn't shrink to less than 250px. For browser with no grid layout support, this demo will use this polyfill, which doesn't support minmax yet. Enable Grid Layout in your browser to properly view the demo. Item 1 Item 2 Item 3 Item 4
    You can also use the auto, min-content and max-content keywords as the min or max values.

    CSS Grid Layout: The Span Keyword

    If you're placing items onto their parent grid with grid-column or grid-row, you can use the span keyword to avoid specifying end lines when items should span more than one column or row. Given the following CSS rule for a grid item, which spans 3 columns and 2 rows: .item { grid-column: 2 / 5; grid-row: 1 / 3; } We can use the span keyword like this instead: .item { grid-column: 2 / span 3; grid-row: 1 / span 2; } The end line can be provided and span used as the start line instead, in which case the span acts in reverse, so the following is also equivalent: .item { grid-column: span 3 / 5; grid-row: span 2 / 3; }
    If multiple lines have the same name, you can define the start and end lines like in the following example: .item { grid-column: col 2 / col 7; grid-row: content 6 / content 10; } The item starts on the column with the 2nd line named col and ends on the 7th line also named col. Similarly, it starts on the 6th line named row and ends on the 10th line named row. And here the span keyword can help also, and the following is equivalent: .item { grid-column: col 2 / span col 5; grid-row: content 6 / span content 4; }
    Span can also be used with the grid-area property. For example, if we want an item to be placed automatically, but to span across a provided number of rows and columns: .item { grid-area: span 6 / span 4; }

    CSS Grid Layout: Named Lines

    The default way to place grid items onto the grid with CSS Grid Layout is by specifying starting and ending grid line numbers. This can quickly become complicated, especially with more complex grids. Named lines offer an alternative to placing items and allow you to name important lines and then place grid items using these named lines. The demos should still work on non-supporting browsers, thanks to this Grid polyfill. First, here's an example with the items placed using line numbers: .container { display: grid; grid-gap: 4px; grid-template-columns: 2fr 1fr 15%; grid-template-rows: 50px 150px 50px; } .header { grid-column: 1 / 3; grid-row: 1; } .content { grid-column: 1 / 2; grid-row: 2; } .content-side { grid-column: 2; grid-row: 2; } .sidebar { grid-column: 3; grid-row: 1 / 4; } .footer { grid-column: 1 / 3; grid-row: 3; } Here's the resulting grid: Header Content Content Side Sidebar Footer
    Now here's the same example, but notice how we define named lines in square brackets as part of the grid-template-columns and grid-template-rows definitions. We define these named lines between the track sizes. We then use these line names on the grid items for the values of grid-column and grid-row: .container { display: grid; grid-gap: 4px; grid-template-columns: [content-start] 2fr [content-end content-side-start] 1fr [content-side-end side-start] 15% [side-end]; grid-template-rows: [header-start] 50px [header-end content-start] 150px [content-end footer-start] 50px [footer-end]; } .header { grid-column: content-start / content-side-end; grid-row: header-start / header-end; } .content { grid-column: content-start / content-end; grid-row: content-start / content-end; } .content-side { grid-column: content-side-start / content-side-end; grid-row: content-start / content-end; } .sidebar { grid-column: side-start / side-end; grid-row: header-start / footer-end; } .footer { grid-column: content-start / content-side-end; grid-row: footer-start / footer-end; } Notice how one line can have multiple names by defining all the names in the same square brackets:
  • [content-end content-side-start]
  • You can name only the lines that are significant for your purposes, and then you can always use a mixture of line numbers and named lines when placing grid items. In the example with named lines, we decided to explicitly define the starting and ending columns and rows, but by default an item will span one column or row, so the property values can be shorter for the same result: .header { grid-column: content-start / content-side-end; grid-row: header-start; } .content { grid-column: content-start; grid-row: content-start; } .content-side { grid-column: content-side-start; grid-row: content-start; } .sidebar { grid-column: side-start; grid-row: header-start / footer-end; } .footer { grid-column: content-start / content-side-end; grid-row: footer-start; }

    CSS Grid Layout: Grid Areas

    With CSS Grid Layout, the default way to place items on their containing grid is by specifying the lines where they start and end. Grid areas are an alternative to providing lines and offer a way to name grid areas so that items can easily fit into these named areas. It may seem a bit confusing at first, but the power of grid areas quickly becomes evident. The demos should still work on non-supporting browsers, thanks to this Grid polyfill.

    Named areas with grid-area

    First you define names of your choice on grid items with the grid-area property: .item-1 { grid-area: head; } .item-2 { grid-area: main; } .item-3 { grid-area: side; } .item-4 { grid-area: footer; }

    Describing the layout with grid-template-areas

    Then, on the grid container, you use the grid-template-areas property to define how the named areas get applied: .container { display: grid; grid-template-columns: 2fr 2fr 1fr 2fr; grid-template-rows: 100px 200px 100px; grid-template-areas: "head head . side" "main main . side" "footer footer footer footer"; } Defining the value for grid-template-areas lets you use ascii art. Each section in quotes is a row and each word represents a column. A . is for an empty grid cell, and it can actually be as many consecutive . characters (i.e: ….). Spaces are not relevant and you can play around with the format. Here for example is an equivalent to the above snippet: .container { /* ... */ grid-template-areas: "head head ..... side" "main main ..... side" "footer footer footer footer"; } And the following is the result: Head Main Side Footer
    Now let's play around with the grid-template-areas value to get something completely different, all without having to touch any of the properties on the grid items. The following example may be a bit too Art Deco for your taste, but it illustrates the power: .container { /* ... */ grid-template-areas: "head head . side" "main main main side" ". footer footer side"; /* ... */ } Head Main Side Footer

    Grid areas with media queries

    The full power of grid areas is unleashed when coupled with media queries. Fully responsive layouts can be achieved with a simple change to a single property: @media screen and (max-width: 40em) { .container { grid-template-areas: "head head head head" "main main main main" "side side side side" "footer footer footer footer"; } } Notice how we change the order of elements without having to touch the source order. On this responsive version we also added a new implicit row that will have a height of auto. CSS Grid takes care of creating the new row for us even if we didn't define that extra row in our grid-template-rows property. If you're on a desktop computer, resize your browser to see the result in action. If you're on a mobile device, you should already see it: Head Main Side Footer

    CSS Grid Layout: Introduction

    Flexbox is great, but its main purpose is to help us with positioning elements in one dimension, either horizontal or vertical. For whole page, two-dimension layout, we've been mostly relying on frameworks like Bootstrap or Foundation to provide us with classes that we can use to create a grid layout. A new module, CSS Grid Layout, set to be available in browsers very soon, should change all of that. Let's explore CSS Grid with a very brief overview. First, a few key points to keep in mind:
  • Like with Flexbox, source order doesn't matter with CSS Grid and items can easily be repositioned depending on the size of the viewport.
  • You can start using grid layout now and use feature detection with @supports so that it's only applied in supporting browsers.
  • Some layouts that are impossible to accomplish even with the grid system of modern CSS frameworks will be possible with CSS Grid.
  • Vocabulary

    A few concepts are introduced with CSS Grid, and it's a good idea to get familiar with the vocabulary:
  • Grid line: items are positioned on the grid with the lines where the item starts and ends, so grid lines are central to how CSS Grid works. Column grid lines are numbered from left to right starting with 1 and row grid lines are numbered from top to bottom starting with 1.
  • Grid Row Line 2

    Grid Line
  • Grid track: The space between two grid lines.
  • Grid track

    Grid track
  • Grid area: An area defined by any 4 grid lines.
  • Grid area

    Grid area
  • Grid cell: The space between two consecutive column and row grid lines. The smallest unit possible on a grid.
  • Grid cell

    Grid cell

    Display: grid on the parent

    A little bit like with flexbox, the grid is organized with a container element and children elements that become grid items. You simply set display: grid on the container element. The grid rows and columns are defined with grid-template-columns and grid-template-rows. Let's start with the following markup: <div class="container"> <div class="box box-1">Box 1</div> <div class="box box-2">Box 2</div> <div class="box box-3">Box 3</div> <div class="box box-4">Box 4</div> <div class="box box-5">Box 5</div> <div class="box box-6">Box 6</div> <div class="box box-7">Box 7</div> </div> Here's how we can define the CSS for the container: .container { display: grid; grid-template-columns: 150px 150px 80px; grid-template-rows: 100px auto; grid-gap: 10px 15px; } With this we already get something interesting, even without setting any properties on the grid items: CSS grid example 1 Notice how we added 10px horizontal gaps and 15px vertical gaps between the cells using grid-gap. Now we can go further by defining the start and end lines of specific items. Items that are not explicitly placed on the grid will be placed according to an algorithm. We use grid-column-start, grid-column-end, grid-row-start and grid-row-end to define where an item starts and ends on the grid: .box-1 { grid-column-start: 1; grid-column-end: 3; } .box-3 { grid-column-start: 1; grid-column-end: 3; grid-row-start: 2; grid-row-end: 4; } Or we can use the grid-column and grid-row shorthands for the same result: .box-1 { grid-column: 1 / 3; } .box-3 { grid-column: 1 / 3; grid-row: 2 / 4; } Here's the resulting grid now: CSS grid example 2 Gaps don't add new grid lines, so items that are next to each other are really touching the same line, even if a gap is separating them.

    CSS Grid Layout today

    Unfortunately Grid Layout is still not available at large. Here's the current availability:
  • Supported by default in Firefox since version 52.
  • Fully supported in the latest Chrome and Opera behind a flag.
  • Supported in IE and Edge, but with an older syntax.
  • Available in the latest Safari Technology Preview.
  • Chrome should be shipping a version with Grid enabled by default in March 2017. So it's coming really soon, and 2017 will most likely be the year of CSS Grid!

    Enable in Chrome

    To enable CSS Grid in Chrome, go to chrome://flags/, look for Experimental Web Platform features and enable it.

    Enable in Firefox

    Grid layout is now supported out of the box with Firefox 52 and up.

    Learning More

    We kept this post short and sweet, but there are many new concepts to learn with CSS Grid, so we split many of them into their own post:
  • The Fr Unit
  • Grid Areas
  • Named Lines
  • The Span Keyword
  • The Minmax Function
  • The Repeat Notation
  • Holy Grail Layout Example
  • grid-auto-flow
  • grid-auto-rows + grid-auto-columns
  • Further reading

    Here are a few great resources to learn the ins and outs of CSS Grid:
  • CSS-Tricks' A Complete Guide to Grid
  • Grid by Example by Rachel Andrew
  • This eBook by Eric A. Meyer
  • These layout demos by Jen Simmons
  • Styling Placeholder Text Using CSS

    Placeholder text will automatically inherit the font family and font size of the regular input text, but you may be in a situation where you want to change the placeholder text color. You can accomplish that with the ::placeholder pseudo-element. In our example, let's define a custom color for our placeholder text, and let's also override the inherited font size to have smaller placeholder text. Here's our base input styling: input[type="text"] { font-family: monospace; font-size: 20px; color: peru; } And here's the styling for our placeholder text: ::-webkit-input-placeholder { color: peachpuff; font-size: 13px; } ::-moz-placeholder { color: peachpuff; font-size: 13px; } :-ms-input-placeholder { color: peachpuff; font-size: 13px; } ::placeholder { color: peachpuff; font-size: 13px; } Unfortunately you can see that ::placeholder requires a slew of vendor prefixes at the moment.

    Inherit, Initial and Unset Values for CSS Properties

    All CSS properties have 3 basic values in common: inherit, initial and unset. Inherit and initial have been around for a long time, but unset is a new addition. What the values will do can at times get confusing, so here's a breakdown:
  • inherit: Get the property from the parent element.
  • initial: The default value for the property (the browser default).
  • unset: Acts as either inherit or initial. It'll act as inherit if the parent has a value that matches, or else it will act as initial.
  • Here's an example to make is clear. Here's our markup: <div class="wrapper"> <p class="one">Snake<p> <p class="two">Lizard<p> <p class="three">Alligator</p> <p>Komodo Dragon</p> </div> And here's our CSS: .wrapper { color: orange; } .wrapper p { color: purple; } p.one { color: inherit; } p.two { color: initial; } p.three { color: unset; }
  • Snake is orange, it inherits from the wrapper div.
  • Lizard is black, it takes the initial browser default value.
  • Alligator is orange, in this case unset acts as inherit because there is a parent with a matching value.
  • Komodo Dragon is purple, the only paragraph that takes its value from the .wrapper p selector.

  • A neat trick with unset is when combined with the all shorthand, which automatically affects all properties of a selector. The following unsets every properties of the selected p elements: article p { all: unset; }

    CSS vertical-align Property

    vertical-align defines the vertical alignment for the content of a table cell or for an inline element against the rest of the inline flow. vertical-align can take a % or length value, or it can take one of the following 8 keywords:
  • baseline: The default. Baseline of the element aligned to the baseline of the parent.
  • bottom: Bottom of the element aligned to the complete bottom of the line.
  • middle: Middle of the element aligned to half the x-height of the parent. The x-height is the height of the text without the character ascenders or descenders.
  • sub: Baseline of the element aligned to the subscript baseline of the parent.
  • super: Baseline of the element aligned to the superscript baseline of the parent.
  • text-bottom: Bottom of the element aligned to the bottom of the text.
  • text-top: Top of the element aligned to the top of the text.
  • top: Top of the element aligned to the top of the line.
  • If a length value is provided, the element is aligned at the specified length above the baseline of the parent. If a % value is provided, the element is aligned at the specified % above the baseline of the parent, with the % being a reference to the line-height. Here's an example using vertical-align: .avatar { vertical-align: middle; }

    Showcase

    It can be hard to imagine the effects of the different keyword values for vertical-align, so here are examples with an inline image placed with different values:

    vertical-align: baseline

    Lee belaying pin Plate Fleet baseline example trysail swab hulk lugger bounty parrel Buccaneer.

    vertical-align: bottom

    Lee belaying pin Plate Fleet bottom example trysail swab hulk lugger bounty parrel Buccaneer.

    vertical-align: middle

    Lee belaying pin Plate Fleet middle example trysail swab hulk lugger bounty parrel Buccaneer.

    vertical-align: sub

    Lee belaying pin Plate Fleet sub example trysail swab hulk lugger bounty parrel Buccaneer.

    vertical-align: super

    Lee belaying pin Plate Fleet super example trysail swab hulk lugger bounty parrel Buccaneer.

    vertical-align: text-bottom

    Lee belaying pin Plate Fleet text-bottom example trysail swab hulk lugger bounty parrel Buccaneer.

    vertical-align: text-top

    Lee belaying pin Plate Fleet text-top example trysail swab hulk lugger bounty parrel Buccaneer.

    vertical-align: top

    Lee belaying pin Plate Fleet top example trysail swab hulk lugger bounty parrel Buccaneer.

    Defining Animations in CSS With @keyframes

    @keyframes is the at-rule to define one animation cycle in CSS. You simply provide values for animatable properties on a percentage-based timeline. The syntax it pretty straightforward: @keyframes fancy { 50% { transform: scale(1.4) rotate(80deg); } 80% { transform: scale(1.2) rotate(40deg); } 100% { transform: scale(1) rotate(0deg); } } In the above, we could have also defined 0% to transform: scale(1) rotate(0deg) to be more explicit, but when either the starting or ending time is not provided, the values are inferred. You would call this animation with the different animation properties, or the animation shorthand: .fancy-box { animation: fancy 1.5s ease-out infinite; } And here's the result of our animation:

    A Few Notes

  • Instead of 0%, you can use the from keyword.
  • Instead of 100%, you can use the to keyword.
  • Even if you use the from and to keywords, any values in between are still declared with a % value.
  • If two of the times have the same values, they can be under the same declaration: 45%, 77% {…}.
  • At least the starting or ending time, 0% or 100%, must be declared for the animation to be valid.
  • Declarations with the !important keyword are ignored.
  • If some un-animatable properties are provided, they will be ignored, but the animatable ones will still work.
  • Browser Support Can I Use css-animation? Data on support for the css-animation feature across the major browsers from caniuse.com.

    CSS pointer-events Property

    pointer-events is very useful when set to none to deactivate the click target and allow elements underneath a certain element to get the click. .no-click { pointer-events: none; } Here for example, our top element covers part of the bottom element, but notice how the wait cursor of the bottom element gets active even when the pointer is still over the top element, because pointer-events is set to none on the top element. If we were to click on the top element where the bottom element is covered, the bottom element would get the click: bottom top

    SVG-only values

    pointer-events can also take a few more values when applied to SVG elements:
  • all: The element is a target when the pointer is over a fill or a stroke.
  • stroke: The element is a target when the pointer is over a stroke.
  • fill: The element is a target when the pointer over a fill.
  • painted: The element is a target when the pointer is on a fill or a stroke and that that fill or stoke are set to something else than none, regardless of the visibility.
  • visible: The element is a target when the pointer is on a fill or a stroke and that that fill or stoke are set to visible, regardless of the value for the fill or stroke.
  • visiblePainted: The element is a target when the pointer is on a fill or a stroke and that that fill or stoke are set to visible and set to something else than none.
  • visibleFill: The element is a target when the pointer is on a fill and that that fill is set to visible, regardless of the value for the fill.
  • visibleStroke: The element is a target when the pointer is on a stroke and that that stroke is set to visible, regardless of the value for the stroke.
  • Browser Support Can I Use pointer-events? Data on support for the pointer-events feature across the major browsers from caniuse.com.

    Reference: CSS Color Names

    HEX, RGB(a) & HSL(a) are all great, but with can also use keyword names for 140 colors. Here's a reference for all of them, along with their HEX equivalent, in alphabetical order. Note that there's really 147 in there, but 7 of them have duplicates (grey and gray for example). Everything is included along with the new color names from CSS3 and rebeccapurple from CSS Color Level 4:
    Name HEX Color
    aliceblue #F0F8FF
    antiquewhite #FAEBD7
    aqua #00FFFF
    aquamarine #7FFFD4
    azure #F0FFFF
    beige #F5F5DC
    bisque #FFE4C4
    black #000000
    blanchedalmond #FFEBCD
    blue #0000FF
    blueviolet #8A2BE2
    brown #A52A2A
    burlywood #DEB887
    cadetblue #5F9EA0
    chartreuse #7FFF00
    chocolate #D2691E
    coral #FF7F50
    cornflowerblue #6495ED
    cornsilk #FFF8DC
    crimson #DC143C
    cyan #00FFFF
    darkblue #00008B
    darkcyan #008B8B
    darkgoldenrod #B8860B
    darkgray #A9A9A9
    darkgreen #006400
    darkgrey #A9A9A9
    darkkhaki #BDB76B
    darkmagenta #8B008B
    darkolivegreen #556B2F
    darkorange #FF8C00
    darkorchid #9932CC
    darkred #8B0000
    darksalmon #E9967A
    darkseagreen #8FBC8F
    darkslateblue #483D8B
    darkslategray #2F4F4F
    darkslategrey #2F4F4F
    darkturquoise #00CED1
    darkviolet #9400D3
    deeppink #FF1493
    deepskyblue #00BFFF
    dimgray #696969
    dimgrey #696969
    dodgerblue #1E90FF
    firebrick #B22222
    floralwhite #FFFAF0
    forestgreen #228B22
    fuchsia #FF00FF
    gainsboro #DCDCDC
    ghostwhite #F8F8FF
    gold #FFD700
    goldenrod #DAA520
    gray #808080
    green #008000
    greenyellow #ADFF2F
    grey #808080
    honeydew #F0FFF0
    hotpink #FF69B4
    indianred #CD5C5C
    indigo #4B0082
    ivory #FFFFF0
    khaki #F0E68C
    lavender #E6E6FA
    lavenderblush #FFF0F5
    lawngreen #7CFC00
    lemonchiffon #FFFACD
    lightblue #ADD8E6
    lightcoral #F08080
    lightcyan #E0FFFF
    lightgoldenrodyellow #FAFAD2
    lightgray #D3D3D3
    lightgreen #90EE90
    lightgrey #D3D3D3
    lightpink #FFB6C1
    lightsalmon #FFA07A
    lightseagreen #20B2AA
    lightskyblue #87CEFA
    lightslategray #778899
    lightslategrey #778899
    lightsteelblue #B0C4DE
    lightyellow #FFFFE0
    lime #00FF00
    limegreen #32CD32
    linen #FAF0E6
    magenta #FF00FF
    maroon #800000
    mediumaquamarine #66CDAA
    mediumblue #0000CD
    mediumorchid #BA55D3
    mediumpurple #9370DB
    mediumseagreen #3CB371
    mediumslateblue #7B68EE
    mediumspringgreen #00FA9A
    mediumturquoise #48D1CC
    mediumvioletred #C71585
    midnightblue #191970
    mintcream #F5FFFA
    mistyrose #FFE4E1
    moccasin #FFE4B5
    navajowhite #FFDEAD
    navy #000080
    oldlace #FDF5E6
    olive #808000
    olivedrab #6B8E23
    orange #FFA500
    orangered #FF4500
    orchid #DA70D6
    palegoldenrod #EEE8AA
    palegreen #98FB98
    paleturquoise #AFEEEE
    palevioletred #DB7093
    papayawhip #FFEFD5
    peachpuff #FFDAB9
    peru #CD853F
    pink #FFC0CB
    plum #DDA0DD
    powderblue #B0E0E6
    purple #800080
    rebeccapurple #663399
    red #FF0000
    rosybrown #BC8F8F
    royalblue #4169E1
    saddlebrown #8B4513
    salmon #FA8072
    sandybrown #F4A460
    seagreen #2E8B57
    seashell #FFF5EE
    sienna #A0522D
    silver #C0C0C0
    skyblue #87CEEB
    slateblue #6A5ACD
    slategray #708090
    slategrey #708090
    snow #FFFAFA
    springgreen #00FF7F
    steelblue #4682B4
    tan #D2B48C
    teal #008080
    thistle #D8BFD8
    tomato #FF6347
    turquoise #40E0D0
    violet #EE82EE
    wheat #F5DEB3
    white #FFFFFF
    whitesmoke #F5F5F5
    yellow #FFFF00
    yellowgreen #9ACD32

    Change the Mouse Cursor in CSS With the cursor Property

    cursor is used to change the mouse cursor on specific elements. This is especially useful in web apps where different tasks can be done other than clicking. This obviously only works when there's a pointing device: .in-progress { cursor: progress; }

    Available Cursors

    Hover over the following to see the different cursors available if you're on a desktop/laptop computer:

    General/Default Cursors

    auto default none

    Link Cursor

    pointer

    Scroll Cursor

    all-scroll

    Status Cursors

    context-menu help wait progress

    Selection Cursors

    crosshair cell text vertical-text

    Drag & Drop Cursors

    alias copy move no-drop not-allowed

    Zoom Cursors

    zoom-in zoom-out

    Grab Cursors

    grab grabbing

    Resizing Cursors

    e-resize n-resize ne-resize nw-resize s-resize se-resize sw-resize w-resize ew-resize ns-resize nesw-resize nwse-resize col-resize row-resize

    Custom Cursors

    You can define custom cursors. Note that not all browsers support svg files for cursors, and .cur files are supported across the board, so it can be a good idea to provide a .cur fallback if you want to use an svg cursor. You can also provide a fallback to one of the non-custom cursors. You can define a custom position for the cursor hotspot by adding x & y coordinates for where the hotspot should be in the provided custom image. Note that, when using svg cursors, it's important that your svg has width & height values on the root svg element, or else your cursor won't show. In the following example, our svg file (chef.svg) starts like this: <svg height="32" width="32"... .custom-cur { cursor: url('/images/chef.svg'); } /* With a .cur fallback */ .custom-cur { cursor: url('/images/chef.svg'), url('/images/chef.cur'); } /* With a custom hotspot */ .custom-cur { cursor: url('/images/chef.svg') 10 12; } /* With a non-custom fallback: */ .custom-cur { cursor: url('/images/chef.svg'), move; } Here's a button with our custom cursor: chef-cur.svg Browser Support Can I Use css3-cursors? Data on support for the css3-cursors feature across the major browsers from caniuse.com.

    CSS border-radius Property

    border-radius is used to create rounded corners on elements. The values can be specified in length or percentage units. border-radius is a shorthand for border-top-left-radius, border-top-right-radius, border-bottom-left-radius and border-bottom-right-radius and values get applied the same way as values for padding & margin get applied (clockwise from the top left to the bottom right): /* All corners equal */ .rounded-box { border-radius: 25px; } /* 40% for top left + bottom right corners */ .rounded-box2 { border-radius: 40% 0; } .rounded-box .rounded-box2 Use a border-radius of 50% on square elements to create a circle: .round-box { border-radius: 50%; } .round-box A lesser known fact is that for each border-radius value you can use / to define different horizontal and vertical radii (fun word ). By default the horizontal and vertical radii have the same value. The value(s) before the / is for the horizontal radius and the value(s) after the / is for the vertical radius. You probably won't need to use this often, but here's an example anyway: .radii-fun { border-radius: 50% / 20%; } /* 10px horizontal radius all around, but distinct vertical radii */ .radii-fun2 { border-radius: 10px / 3px 15px 25px 45px; } .radii-fun .radii-fun2 Browser Support Can I Use border-radius? Data on support for the border-radius feature across the major browsers from caniuse.com.

    Inline vs Inline-Block Display in CSS

    display: inline-block brought a new way to create side by side boxes that collapse and wrap properly depending on the available space in the containing element. It makes layouts that were previously accomplished with floats easier to create. No need to clear floats anymore. Compared to display: inline, the major difference is that inline-block allows to set a width and height on the element. Also, with display: inline, top and bottom margins & paddings are not respected, and with display: inline-block they are. Now, the difference between display: inline-block and display: block is that, with display: block, a line break happens after the element, so a block element doesn't sit next to other elements. Here are some visual examples:

    display: inline

    Notice here how the width and height are not respected, and how the padding top and bottom are present, but overlap over the lines above and under. span.box { display: inline; /* the default for span */ width: 100px; height: 160px; padding: 18px; } Cheese and wine ricotta danish fontina. Brie cheesy grin paneer squirty cheese taleggio cheesecake goat taleggio goat taleggio. Bavarian bergkase emmental fromage cheesecake cheese slices cheesy grin queso caerphilly.

    display: inline-block

    Here the width, height and padding are respected, but the two copies of the element can still sit side by side. span.box { display: inline-block; width: 100px; height: 160px; padding: 18px; } Cheese and wine ricotta danish fontina. Brie cheesy grin paneer squirty cheese taleggio cheesecake goat taleggio goat taleggio. Bavarian bergkase emmental fromage cheesecake cheese slices cheesy grin queso caerphilly.

    display: block

    Here again everything is respected, but the elements don't sit side by side. span.box { display: block; width: 100px; height: 160px; padding: 18px; } Cheese and wine ricotta danish fontina. Brie cheesy grin paneer squirty cheese taleggio cheesecake goat taleggio goat taleggio. Bavarian bergkase emmental fromage cheesecake cheese slices cheesy grin queso caerphilly. Browser Support Can I Use inline-block? Data on support for the inline-block feature across the major browsers from caniuse.com.

    CSS box-sizing Property

    box-sizing defines how the width and height gets applied on an element. It can be useful to play with box-sizing if, for example, an element needs to take a precise amount of space on a page, with its padding and border included. It can take two possible values:
  • content-box: The width & height of the element only include the content. In other words, the border, padding and margin aren't part of the width or height. This is the default value.
  • border-box: The padding and border are included in the width and height.
  • There was also a padding-box value, but it's now deprecated and should no longer be used. Here's an example to illustrate the two possible values:

    box-sizing: content-box

    Notice that with content-box the element ends up taller and wider than the specified dimensions because the border and padding fall outside of those dimensions. .alligator-box { box-sizing: content-box; width: 125px; height: 125px; border-width: 10px; padding: 40px; }

    box-sizing: border-box

    .alligator-box { box-sizing: border-box; width: 125px; height: 125px; border-width: 10px; padding: 40px; }

    CSS background-size Property

    background-size defines the size of a background image within its containing element. background-size can be defined with either length, percentage or keyword* values. The 2 possible keywords are:
  • contain: Scales the image as much as possible while keeping the aspect ratio and avoids clipping the image.
  • cover: Again, scales the image and maintains its aspect ratio, but this time the image will fill the whole area of the element and some clipping may occur.
  • When providing a percentage value, it's a percentage of coverage of the containing element. To define both a width and a height, you'll provide 2 space-separated values. Therefore, background-size: 30% 40% would be for a width of 30% and a height of 40%. If only one value is provided, the height will be set to auto. When an element has multiple background images, you can also define a list of comma-seperated size values to define different sizes for each image. Let's see the effects of the two keywords: contain & cover:

    background-size: contain

    .alligator-show-box { background-size: contain; background-image: url(/images/police.svg); }

    background-size: cover

    .alligator-show-box { background-size: cover; background-image: url(/images/police.svg); }

    CSS background-repeat Property

    background-repeat defines if and how a background image should be repeated within an element if the image doesn't fully cover the element. 7 keywords can be used for the background-repeat property:
  • repeat: The default. Simply tiles the background on the x and y axis.
  • no-repeat: The background image is only shown once.
  • repeat-x: Repeat on the x axis.
  • repeat-y: Repeat on the vertical axis.
  • space: The image is repeated as much as possible while avoiding clipping. The 1st and last copies of the image are placed to either side of the containing element.
  • round: The images will stretch or shrink slightly to avoid clipping and to produce no gaps.
  • You can use 2 space-separated values to define the repeat value for the x axis and y axis. For example, repeat no-repeat is the equivalent of repeat-x. repeat, no-repeat, repeat-x and repeat-y are very common and you're probably used to their behavior already. With these keywords, clipping of the image will occur if a copy only partly fits. Let's give an example of the other 2 possible values, space and round, defined in CSS Backgrounds and Borders Module Level 3 (the CSS3 module for backgrounds and borders). If you can, adjust your browser window's size to better notice the effect. Note that, as of this writing, Firefox doesn't support space or round yet, it falls back to no-repeat instead.

    background-repeat: space

    .alligator-show-box { background-size: 150px; background-repeat: space; background-image: url(/images/cowboy.svg); }

    background-repeat: round

    .alligator-show-box { background-size: 150px; background-repeat: round; background-image: url(/images/pirate.svg); }

    CSS white-space Property

    white-space is a CSS property that helps control how whitespace and line breaks within an element's text are treated. The white-space property can take these values:
  • normal: The default value. Multiple whitespaces are collapsed into one. The text wraps to the next line when needed.
  • nowrap: Multiple whitespaces are collapsed into one, but the text doesn't wrap to the next line. We've already discussed how to use the nowrap value to prevent line breaks.
  • pre: Same results as using the <pre> where all the whitespaces will be kept as is and the text only wraps when line breaks are in the content.
  • pre-line: Multiple whitespaces are collapsed into one, the text breaks to the next line when needed or with line breaks in the content.
  • pre-wrap: Similar to pre, but the text also wraps when needed.
  • white-space: normal

    Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

    white-space: nowrap

    Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

    white-space: pre

    Here I manually included line breaks and extra spaces. Notice the extra line break at the beginning. That's because in the markup the text start on the line after the <p> element. Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

    pre-line

    Here the text breaks when needed, but I also manually broke the last few words. I included the same extra whitespaces, but they are now collapsed. Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

    pre-wrap

    Now the extra whitespaces aren't collapsed. Medusafish banded killifish convict blenny saury threadsail beluga sturgeon. Indian mul mora cisco masu salmon, roosterfish requiem shark longnose lancetfish bluefish red snapper Sacramento splittail giant danio.

    A CSS Selector Reference

    A reference of CSS selectors. This includes new selectors from CSS Selectors Level 3 (CSS3):

    Universal Selector: *

    Selects everything.

    Root Element Selector: :root

    Selects the root element. All elements are descendants of the root element, and it almost always references the <html> element.

    Type Selector: h3

    Selects all elements of the type.

    ID selector: #myEl

    Selects the element with the provided ID.

    Class selector: .btn-xl

    Selects all elements with the provided class.

    Attribute selectors

    Simple Attribute Selector: [target]

    Selects elements that have the provided attribute.

    Attribute & Value Selector: [target=”_blank”]

    Selects elements that have the provided attribute and value.

    Attribute & One of Many Values: [class~=”large”]

    Selects elements if the value is part of a white-space separated list of values.

    Attribute & Beginning of a Value: [target^=”_b”]

    Selects elements who's value for an attribute starts with the provided string.

    Attribute & End of a Value: [target$=”nk”]

    Selects elements who's value for an attribute ends with the provided string.

    Attribute & Part of a Value: [target*=”lan”]

    Selects elements who's value for an attribute contains the substring provided.

    Attribute & Part of a Hyphen-Separated List of Values: [lang|=”zu”]

    Selects elements if the value is the left part in a hyphen-separated list.

    Descendant Selector: h3 span

    Selects the element(s) provided on the right if it's a descendant of the element on the left.

    Child Selector: div > p

    Selects the element(s) provided on the right if it's a direct child of the element on the left.

    Adjacent Sibling Selector: div + p

    Selects the element provided on the right if it's immediately preceded by the element on the left.

    General Sibling Selector: div ~ p

    Selects the element provided on the right if it's preceded by the element on the left.

    Negation Selector: :not(.first-par)

    Selects elements that don't match the simple selector provided in parenthesis.

    Pseudo-Elements

    ::before Pseudo-Element: p::before

    Generated content before the element.

    ::after Pseudo-Element: p::after

    Generated content after the element.

    ::first-letter Pseudo-Element: p::first-letter

    The first letter of the element.

    ::first-line Pseudo-Element: p::first-line

    The first line of the element.

    Structural Pseudo-Classes

    nth-child(n): span:nth-child(5)

    Selects the n-th sibling if it's the provided type.

    nth-last-child(n): p:nth-last-child(4)

    Counting from the last child, selects the n-th sibling if it's the provided type.

    nth-of-type(n): span:nth-of-type(2)

    Selects the n-th sibling, only counting the same type.

    nth-last-of-type(n): span:nth-last-of-type(3)

    Counting from the last child and only counting the provided type, selects the n-th sibling.

    first-child: span:first-child

    Selects the first of child of the parent if it matches the provided type of element.

    last-child: span:last-child

    Selects the last of child of the parent if it matches the provided type of element.

    first-of-type: span:first-of-type

    Selects the first of the provided type within a parent.

    last-of-type: span:last-of-type

    Selects the last of the provided type within a parent.

    only-child: span:only-child

    Selects the element if it's the only child of the parent element.

    only-of-type: span:only-of-type

    Selects the element if it's the only one of its type inside the parent element.

    empty: div:empty

    Selects elements with no children.

    Link Pseudo-Classes

    Link: a:link

    A link that hasn't been visited. The starting point for links

    Visited: a:visited

    A link that has been visited.

    User Action Pseudo-Classes

    Active: a:active

    When the element is active.

    Hover: a:hover

    When the user's pointing device is on top of the element.

    Focus: a:focus

    When the element has the focus. For example, when the user clicks inside an input field, the field has the focus.

    Target Pseudo-Class: p:target

    Selected when the element on the left is the current target as defined by the url.

    lang Pseudo-Class: :lang(en)

    Element(s) with the specified lang attribute.

    UI States Pseudo-Classes

    Enabled: input:enabled

    When the element(s) on the left is enabled.

    Disabled: input:disabled

    When the element(s) on the left is disabled.

    Checked: input:checked

    When the element(s) on the left is checked. Associated with the inputs of type radio or checkbox.
    Remember that to target multiple selectors in one CSS declaration you use a comma between each selector. The following example selects all <p> elements that don't have the article-par class and also selects all <h3> elements: p:not(.article-par), h3 { font-weight: bold; } Also, if you want to select an element while targeting a combination of multiple classes and/or ID, you'll simple note the multiple classes and/or ID without using a space between them. For example, if you want to select and element that has the btn and btn-large classes: .btn.btn-large { font-weight: bold; } In the above example, you don't want your selector to be .btn .btn-large, because then it would select .btn-large elements that are descendants of .btn elements. Now say that the element you want to select also has an ID of #main-btn: #main-btn.btn.btn-large { font-weight: bold; }

    CSS background-position Property

    background-position is a CSS property allows us to define where a background image should be positioned within an element. The background-position property can take length, percentage or keyword values. The available keywords are top, bottom, right, left and center. The keywords can be used in any order, and when only one keyword is used the other is assumed to be set to center. If an element has multiple background images, you can define a comma-separated list of background-position values in the same order as the background images are defined.

    A Few Examples

    Keyword Values

    .alligator-show-box { background-size: 25%; background-repeat: no-repeat; background-image: url(/images/police.svg), url(/images/doctor.svg), url(/images/pirate.svg), url(/images/cowboy.svg), url(/images/chef.svg); background-position: top left, top right, center, bottom, left bottom; }

    Percentage & Length Values

    .alligator-show-box2 { background-size: 25%; background-repeat: no-repeat; background-image: url(/images/police.svg), url(/images/doctor.svg), url(/images/pirate.svg), url(/images/cowboy.svg), url(/images/chef.svg); background-position: 75% 0, 100%, 20px 20px, 50%, 0 90%; }

    The :not Pseudo-Class in CSS

    Select elements that don't match a certain selector with :not. Provide a simple selector as an argument to :not and all the elements that don't match will be selected. This first example will select all p elements that don't have a first-par class: p:not(.first-par) { background-color: #E4AF4C; } This second example, we're selecting the ::before pseudo-element for all list items (li) that are inside an unorganized list (ul) that doesn't have an ID of toc or a class of in-list: ul:not(#toc, .in-list) li::before { /* Something stylish */ } And in this third example we're selecting everything inside article elements that's not a span: article *:not(span) { color: cornsilk; } :not is supported in all modern browsers.

    The CSS text-shadow property

    The CSS text-shadow property is similar to the box-shadow property, but the shadow is applied to each letter instead of the boundaries of the element: text-shadow: 2px 2px 1px rgba(0,0,0,0.4); The values go in this order: offset-x, offset-y, blur-radius and color. You can also define multiple shadows: text-shadow: 45px 25px 4px rgb(25,93,229), 25px 15px 1px rgb(25,93,229); Note that, as with the box-shadow property, you can define multiple comma-separated shadows. Unlike with box-shadow however, you can't define a spread value or use the inset keyword for text shadows. There are ways to create a text shadow that looks like an inset shadow, but the shadow itself won't actually be inset.

    Result

    Here's the result of the 2 text shadows from the above snippet: I'm just some text in the world with a basic shadow. I'm just some text in the world with two shadows.

    Preventing Line Breaks Using CSS

    Sometimes you'll want to have short blocks of text always stay on the same line. It's easy to prevent line breaks for specific elements using the CSS white-space property: span.nobreak { white-space: nowrap; } And you can improve upon that in some occasions by hiding any text that would overflow and adding an ellipsis: span.nobreak { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } Another way to prevent a line break for just a one-off string of text would be to use non-breaking spaces (&nbsp;) straight in your HTML. Here's an example using When The Levee Breaks: When&nbsp;nbsp;The&nbsp;nbsp;Levee&nbsp;nbsp;Breaks

    Line Breaks in the CSS Content Property

    The CSS content property is very useful for generated content in the ::before or ::after speudo-elements. To insert a new line / line break in that content, use the \A escape characters: article h3::before { content: "Killing \A Me \A Softly"; white-space: pre-wrap; }

    White-space property

    In order for the new lines to work properly, you also need to set the white-space property to either pre or pre-wrap.

    HTML entities in the CSS Content Property

    Insert special characters and symbols inside generated CSS content using their hex notation instead of the usual HTML entity notation. For example, &copy; becomes \00a9: Here's another example: .foo::before { content: "An ellipsis\2026"; }

    Cheatsheet & conversion tool

  • Here's a great cheatsheet to find the CSS notation for different symbols.
  • And here's a tool to convert HTML entities to their CSS notation.
  • CSS Quick Tip: :before vs ::before & :after vs ::after

    ::before and ::after are pseudo-elements, and with CSS3 the use of two semicolons became the standard to differentiate between pseudo-elements and pseudo-classes. Browsers still all support the old syntax with one semicolon. Only IE8 doesn't support the new syntax. The following two snippets are equivalent, with the first being the modern CSS3 implementation and the second being the obsolete CSS2 implementation, which you'll still need to use if you want to support IE8: .bar::before { content: "foo"; } .bar:before { content: "foo"; } You probaly don't need to support IE8. Just use ::before and ::after will you!

    The CSS attr() Function

    attr() is a CSS function that returns the value of a property. That means that you can define content in your html markup using any custom property and then fetch the value using attr(). It only works on the content property at the moment, but support for other properties are currently in the experimental stage. An example should help explain. First, the HTML markup: <span data-tooltip="Cascading Style Sheets">CSS</span> And now the CSS: [data-tooltip]::before { content: attr(data-tooltip); } [data-tooltip]:hover::before { visibility: visible; opacity: 1; } And with this you can create custom tooltips in pure CSS. Browser Support Browser info is for properties other than content. attr() works across all browsers for content. Can I Use css3-attr? Data on support for the css3-attr feature across the major browsers from caniuse.com.

    Radial Gradients in CSS

    You can now easily define radial and linear gradients in CSS. No need to create images in a seperate software anymore. They are still generated images internally to the browser, so you'll want to define them in the background property or your elements, and you get plenty of flexibility for the direction and color stops. Here we'll explore the syntax for defining radial gradients. See this post for lineal gradients. /* Simplest Case */ .box { background: radial-gradient(black, white); } /* A circle as the center shape instead of an ellipse and a 3rd color stop */ .box { background: radial-gradient(circle, #211533, #211533, #3e275f); } /* Control the size of the gradient */ .box { background: radial-gradient(farthest-corner at 10px 10px, #211533 40%, #3e275f); } .box2 { background: radial-gradient( farthest-side circle at 10px 10px, #211533 40%, #3e275f); }

    Default color for browsers that don't support gradients

    It's a good idea to define a default base color that older browers will fall back on: .box { background: #211533; background: radial-gradient(to top, #211533, #211533, #3e275f); } Browser Support Can I Use css-gradients? Data on support for the css-gradients feature across the major browsers from caniuse.com.

    Linear Gradients in CSS

    You can now easily define radial and linear gradients in CSS. No need to create images in a seperate software anymore. They are still generated images internally to the browser, so you'll want to define them in the background property or your elements, and you get plenty of flexibility for the direction and color stops. Here we'll explore the syntax for defining lineal gradients. See this post for radial gradients. /* Simplest Case */ .box { background: linear-gradient(black, white); } /* Defining a direction and adding a 3rd color stop */ .box { background: linear-gradient(to top, #211533, #211533, #3e275f); } /* Direction in degrees instead */ .box { background: linear-gradient(135deg, #211533, #211533, #3e275f); } /* Control over the position of the color stops */ .box { background: linear-gradient(135deg, #211533 20%, #211533 40%, #3e275f); }

    Direction

    You can define a linear gradient's direction in degrees or using one of these keywords: top bottom, to top, to right, to left, to top left, to top right, to bottom left, to bottom right.

    Default color for browsers that don't support gradients

    It's a good idea to define a default base color that older browers will fall back on: .box { background: #211533; background: linear-gradient(to top, #211533, #211533, #3e275f); } Browser Support Can I Use css-gradients? Data on support for the css-gradients feature across the major browsers from caniuse.com.

    The CSS :checked Pseudo-Class Selector

    :checked is a pseudo-class selector that's used to style the checked state of radio, checkbox or option elements: :checked { background-color: hotpink; } /* Only style checked checkboxes */ input[type="checkbox"]:checked { padding-left: 1em; }

    Explicit styling unchecked elements

    You can use the :not pseudo-class with :checked to explicit style unchecked elements. This can be useful if there are certain styles that you don't want to see applied to the checked state: input:not(:checked) { opacity: 0.6; } Browser Support Can I Use css-sel3? Data on support for the css-sel3 feature across the major browsers from caniuse.com.

    The CSS :matches() Pseudo-Class

    :matches() is a new CSS pseudo-class that allows to save time by grouping selectors together: :matches(article, div.section, section) h3 { font-size: 3em; } /* Is this equivalent of this: */ article h3, div.section h3, section h3 { font-size: 3em; } Here's another example to bring home the point: :matches(.main, p, div.my-stuff) :matches(h1, h3, h3, h4) { border: 2px dotted rgba(255,134,34,0.5); } /* Is this equivalent of this: */ .main h1, .main h3, .main h3, .main h4, p h1, p h3, p h3, p h4, div.my-stuff h1, div.my-stuff h3, div.my-stuff h3, div.my-stuff h4 { border: 2px dotted rgba(255,134,34,0.5); } Lots of time saved typing all of this in this second example! This can really help make your CSS files smaller too. Browser Support Myth is a good option to start using :matches() today. Can I Use css-matches-pseudo? Data on support for the css-matches-pseudo feature across the major browsers from caniuse.com.

    A Brief Intro to CSS Variables (Custom Properties)

    Variables in pure CSS without a preprocessor of any kind are available today in most modern browsers. They are officially called custom properties and allow avoiding much of the repetition involved with traditional CSS, and, contrary to variables with preprocessors, they can be changed dynamically. Here's how to use custom properties: /* Declaration */ some-element { --my-bg-color: #F9EC31; } /* Using it */ some-element { background-color: var(--my-bg-color); } You can also provide a fallback value when using a variable, which will be used if the variable hasn't been defined: some-element { background-color: var(--my-bg-color, papayawhip); }

    :root

    A common use case is to define variables in the :root pseudo-class and then use it anywhere the value is needed: :root { --funky-shadow: 3px 3px 10px brown; } .ugly-box { box-shadow: var(--funky-shadow); }

    Calc()

    You can also use calc() on variable values: :root { --special-padding: 1.5em; } .pandora-box { padding-bottom: calc(var(--special-padding) + 1em); } Browser Support Myth is a good option to start using CSS variables today. Can I Use css-variables? Data on support for the css-variables feature across the major browsers from caniuse.com.

    A CSS Flexbox Primer

    Flexbox is a great way to get more flexibility in your layouts and to simplify responsive layout design. It makes it easy to align elements on a 2D plane and is pretty easy to use once you get familiar with the main properties. The first step is to set display: flex on a container element. The children to the flex container become flex items. A set of properties can be applied to flex containers, and have an effect to all the items as a whole, and a different set of properties can be applied to flex items and have their effect on the targeted items. Flex items can in turn also be flex containers for the elements it contains, making it easy to create complex layouts. It's likely that you'll want to support browsers that require you to use vendor prefixes for Flexbox to work properly. You can use something like autoprefixer to make your life easier. Following is a quick primer to help make sense of Flexbox at a glance. This won't be an exhaustive list of all the available properties, values and edge cases, but rather a quick rundown of the most useful or commonly used properties. For an in-depth guide, try this excellent Flexbox guide.

    Contents

    Flex container properties

  • display: flex
  • flex-direction
  • justify-content
  • align-items
  • align-content
  • flex-wrap
  • Flex item properties

  • align-self
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • Flex Container Properties

    Here's a container with 3 span flex items, without Flexbox: <div class="container"> <span class="item pirate"> <img src="/images/pirate.svg" width="50" alt="Item 1"> </span> <span class="item police"> <img src="/images/police.svg" width="50" alt="Item 2"> </span> <span class="item doctor"> <img src="/images/doctor.svg" width="50" alt="Item 3"> </span> </div> Item 1 Item 2 Item 3

    display: flex

    Now, let's improve it automagically simply by setting display: flex on the container. Notice how the items now automatically expand to the available space in the container: .container { display: flex; } Item 1 Item 2 Item 3

    flex-direction

    You can change the direction of the items using the flex-direction property: .container { display: flex; flex-direction: column; } Item 1 Item 2 Item 3 The default is row and the additional available values are row-reverse, column, column-reverse. row-reverse and column-reverse change the visual order of the items, without having to change the order of the HTML markup: .container { display: flex; flex-direction: column-reverse; } Item 1 Item 2 Item 3 The ability to change between the row and column directions makes it very easy to adapt layouts on smaller devices with just one CSS rule change in a media query.

    justify-content

    Use justify-content to align the items on the main axis. The main axis is the Y axis when flex-direction is column and the X axis when flex-direction is row. The default value is flex-start and the additional available values are flex-end, center, space-between, space-around and space-evenly. Item 1 Item 2 Item 3

    align-items

    align-items is analogous to justify-content, but allows to align the items in the cross-axis. It defaults to stretch and also accepts flex-start, flex-end, center and baseline: Item 1 Item 2 Item 3

    align-content

    align-content is similar to align-items, but it only has an effect when there's more than one line of flex items (see flex-wrap below). It defaults to stretch and also accepts flex-start, flex-end, center, space-between, space-evenly: Item 1 Item 2 Item 3

    flex-wrap

    By default items won't wrap (default of nowrap), so if the items take more space than what's available they'll overflow. This can be fixed with flex-wrap set to a value of wrap: Item 1 Item 2 Item 3

    Flex Item Properties

    align-self

    align-self is just like align-items, but only for specific items. This makes it easy to have flex items that break out of the main rule: Item 1 Item 2 Item 3

    flex-grow

    With flex-grow we can control the amount of space that a flex item takes compared to the other items. flex-grow accepts a numeric value and it represents a fraction of the available space, depending on the flex-grow value of the other items. It defaults to a value of 0, which means that the item won't take up available empty space. Since it's based on proportion, setting all items to, for example, a flex-grow of 200 is the same as setting all items to a flex-grow of 1. In the below example, the first item has a default flex-grow value of 0, the second item has a value of 1 and the third item has a value of 2: Item 1 Item 2 Item 3

    flex-shrink

    flex-shrink is the opposite of flex-grow and defines the shrinkability of items. It defaults to a value of 1, meaning that the items can shrink and, just as with flex-grow, it's based on proportion with the other items.

    flex-basis

    flex-basis defines the starting space that an item takes, but it's not a guarantee because it also depends on space availability or if there's extra space to fill. To illustrate, in the following example, all items have a flex-basis of 25%: Item 1 Item 2 Item 3 …but now let's also give a flex-grow of 1 to the first flex item. In the following example, all items have a flex-basis of 25%, but the first item takes up the rest of the available space because it has a flex-grow value of 1: Item 1 Item 2 Item 3 …and finally, here our third item has a flex-basis of 77% and refuses to shrink to make space for the other items that have a flex-basis of 25% because it has a flex-shrink value of 0: Item 1 Item 2 Item 3 .pirate, .police { flex-basis: 25%; } .doctor { flex-basis: 77%; flex-shrink: 0; }

    flex

    flex is a shorthand property for the combination of flex-grow, flex-shrink and flex-basis. For example, here's the syntax for an item that has a flex-grow value of 2, flex-shrink value of 0 and flex-basis of 2rem: .doctor { flex: 2 0 2rem; } Browser Support Can I Use flexbox? Data on support for the flexbox feature across the major browsers from caniuse.com.

    A Few Cool CSS box-shadow Examples

    Thanks to CSS3, we don't have to rely on image editors anymore to create great drop shadows. Here you'll find a few nice drop shadow examples. Get inspired by these to create your own designs. Refer to the box-shadow shorthand snippet for help with the syntax of the box-shadow property.

    Colored Shadows

    Colored drop shadows are hip right now, so here you go: Colored box shadow 1 .shadow1 { box-shadow: 0 20px 50px rgba(59, 43, 91, 0.7); } Colored box shadow 2 .shadow2 { box-shadow: 0 20px 50px rgba(240, 46, 170, 0.7); } Colored box shadow 2 .shadow3 { box-shadow: 0 20px 50px rgba(8, 112, 184, 0.7); }

    Multiple Shadows

    Separate multiple drop shadow definitions with a comma and create has many drop shadows as you want on elements: Multiple box shadows 1 .shadow4 { box-shadow: 0px 10px 1px #ddd, 0 10px 20px #ccc; } Multiple box shadows 2 .shadow5 { box-shadow: -10px -10px 30px 4px rgba(0,0,0,0.1), 10px 10px 30px 4px rgba(45,78,255,0.15); } Multiple box shadows 3 .shadow6 { box-shadow: 5px 5px rgba(0, 98, 90, 0.4), 10px 10px rgba(0, 98, 90, 0.3), 15px 15px rgba(0, 98, 90, 0.2), 20px 20px rgba(0, 98, 90, 0.1), 25px 25px rgba(0, 98, 90, 0.05); } Multiple box shadows 3 .shadow7 { box-shadow: 0 5px rgba(93, 64, 55, 0.4), 0 10px rgba(93, 64, 55, 0.3), 0 15px rgba(93, 64, 55, 0.2), 0 20px rgba(93, 64, 55, 0.1), 0 25px rgba(93, 64, 55, 0.05), -5px 5px 40px rgba(100, 0, 0, 0.4); }

    Inset Shadows

    Use the inset keyword to create inner-shadows: Multiple box shadows 3 .shadow8 { box-shadow: 5px 5px rgba(0, 98, 90, 0.4), 10px 10px rgba(0, 98, 90, 0.3), 15px 15px rgba(0, 98, 90, 0.2), 20px 20px rgba(0, 98, 90, 0.1), 25px 25px rgba(0, 98, 90, 0.05); } Multiple box shadows 3 .shadow9 { box-shadow: 0 -20px 15px -10px rgba(255, 255, 0, 0.3) inset, 0 20px 15px -10px rgba(255, 255, 0, 0.3) inset, 0 0 10px rgba(0, 0, 0, 0.1); } Multiple box shadows 3 .shadow10 { box-shadow: inset -12px -8px 40px #464646; }

    The CSS Box Model

    New to CSS? The first order of business is to understand how the box model works. Every element on a page should be seen as a box, with possible paddings, borders and margins. Here's how it gets applied: ContentPaddingBorderMarginTopBottomRightLeft Note that if you apply a box-shadow to an element that's not an inset box shadow, it'll show outside the border, no matter the margins.

    CSS Padding & Margin Shorthand Properties

    It took me a while to remember how paddings or margins get applied from the shorthand, so here's a quick visual reminder. This is not just for paddings or margins either, but any shorthand that have to do with the edges of a box, like border-width for example: CSS shorthands for padding

    CSS Filter Examples and Quick Demos

    Let's have fun with CSS filters and show you some examples:

    Base image

    Below is the base photograph I'll be using to demonstrate the effects. It's shot that I took and made available on multicolor.io: Base Image

    Blur

    .blur { -webkit-filter: blur(5px); filter: blur(5px); }

    Brightness

    .brightness { filter: brightness(0.9); }

    Contrast

    .contrast { -webkit-filter: contrast(200%); filter: contrast(200%); }

    Grayscale

    .grayscale { -webkit-filter: grayscale(100%); filter: grayscale(100%); }

    Hue-rotate

    .hue-rotate { -webkit-filter: hue-rotate(185deg); filter: hue-rotate(185deg); }

    Invert

    .invert { -webkit-filter: invert(100%); filter: invert(100%); }

    Saturate

    .saturate { -webkit-filter: saturate(200%); filter: saturate(200%); }

    Sepia

    .sepia { -webkit-filter: sepia(80%); filter: sepia(80%); }

    Multiple filters

    You can combine multiple filters to create interesting effects:

    Contrast + Grayscale

    .multiple1 { -webkit-filter: contrast(1.9) grayscale(1); filter: contrast(1.9) grayscale(1); }

    Invert + Hue-rotate

    .multiple2 { -webkit-filter: invert(90%) hue-rotate(175deg); filter: invert(90%) hue-rotate(175deg); }

    Brightness + Saturate + Contrast + Hue-rotate

    .multiple3 { -webkit-filter: brightness(0.7) saturate(150%) contrast(190%) hue-rotate(30deg); filter: brightness(0.7) saturate(150%) contrast(190%) hue-rotate(30deg); }

    Feature Detection in CSS with @supports

    A new at-rule in CSS, @supports, allows you to easily detect if a certain CSS feature is available or not in the visitor's browser. This allows you to make use of these features only for supported browsers or define specific rules only for browsers without support, and have other browsers completely ignore them. @supports is a pure CSS way to replace a tool like Modernizr. @supports allows you to test for both the support of a feature and the non-support of a feature: @supports (column-count: 3) { div { column-count: 3; } }

    Non-support

    Here's how you would test and apply specific rules when a feature is not supported: @supports not (display: flex) { .sidebar { float: left; } }

    Chain multiple CSS features using and / or operators:

    @supports (display: flex) or (display: -webkit-box) or (display: -webkit-flex) or (display: -ms-flexbox) { .menu { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; } }

    One big caveat

    There's one major caveat to @supports right now: @supports itself is not universally supported. It's not supported in Internet Explorer at all, not even version 11, and is has only been supported in Safari for iOS since v9.2. See the @supports Can I Use page for more details. Because of that, it might be more practical to continue using Modernizr for some time, until most IE users have switched over to Edge. @supports also has an handy JavaScript API that can be used to detect for features in JS.

    CSS Attribute Selector

    Selecting elements based on their attributes and attribute values is very powerful. This checks for the presence of an attribute: a[title] { background-color: yellow; } And this checks for an attribute with a specific value: a[target="_blank"] { background-color: hotpink; }

    But wait, there's more!

    You can do a whole lot more:
  • [attribute~="foo"] : Checks if value contains the word foo.
  • [attribute|="foo"] : Checks if value starts with the word foo.
  • [attribute^="foo"] : Checks if value starts with the letters foo.
  • [attribute$="foo"] : Checks if value ends with foo.
  • [attribute*="foo"] : Checks if value contains the letters foo.
  • Change the Selected Text Color in CSS

    It's now easy to change which color the selection will be using CSS. Go ahead and try selecting this very text, you'll see it's purple and the text itself goes white: ::-moz-selection { background-color: #EFBB35; color: #fff; } ::selection { background-color: #EFBB35; color: #fff; }

    Limited properties

    Only color, background, cursor and outline can be set for selections.

    CSS Animation Shorthand Property

    Run your animations easily with the CSS animation shorthand: animation: crazy 4s ease-in-out 0.5s 12 backwards;
  • crazy: Animation name
  • 4s: Duration
  • ease-in-out: Timing function
  • 0.5s: Delay
  • 12: Iteration count
  • backwards: Fill mode
  • Timing-function

    animation-timing-function can take one of the following values: linear, ease, ease-in, ease-out, ease-in-out or cubic-bezier(…).

    Fill-mode

    animation-fill-mode can take one of the following values: none, forwards, backwarts or both.

    CSS Transition Shorthand Property

    Shift between two CSS values in style and save time with the transition shorthand: transition: margin-top 1s ease-in-out 0.5s; Is equivalent to this: transition-property: margin-top; transition-duration: 1s; transition-timing-function: ease-in-out; transition-delay: 0.5s; Use all as the property to affect all values at once. Define multiple transitions in the shorthand using comas: .box { transition: margin-top 1s linear, margin-bottom 0.5s cubic-bezier(0,1.18,.87,.32), margin-left 2s; }

    CSS Border Shorthand Property

    The CSS border shorthand is a simple one and allows you to combine border-width, border-style and border-color into one property: border: 5px dashed #DF5B9C; Each side also has a shorthand: border-bottom: 2px solid #00BDA7;

    Border-style

    border-style can take one of the following values: dashed, dotted, double, groove, ridge, inset, outset, solid, hidden, none, initial or inherit.

    CSS Box-Shadow Shorthand Property

    Box shadows created with CSS are fun and easy, especially when using the shorthand: box-shadow: 5px 5px 3px 1px rgba(0,0,0,0.4); The values go in this order: offset-x, offset-y, blur-radius, spread-radius and color. You can also define inset shadows: box-shadow: inset 5px 5px 3px 1px rgba(0,0,0,0.4); And even multiple box shadows: box-shadow: 5px 5px pink, -5px -5px orange;

    Result

    Here's the result of the 3 shadows from the above snippets. These look like high-class vomit, but it gives you an idea: You can see a few more box-shadow examples here. Browser Support Can I Use css-boxshadow? Data on support for the css-boxshadow feature across the major browsers from caniuse.com.

    CSS Font Shorthand Property

    Somehow it seems like people tend to shy away from using the CSS font shorthand. Maybe because it's so damn hard to remember how to declare it. Well here you go, you can omit everything except font-size and font-family: font: italic small-caps bold 18px/120% "Josefin Sans", sans-serif; Is equivalent to this: font-style: italic; font-variant: small-caps; font-weight: bold; font-size: 18px; line-height: 120%; font-family: "Josefin Sans", sans-serif;

    CSS Background Shorthand Property

    Life's too short to lose time with background properties. Use the shorthand instead. Of course, you don't have to specify a value for every property, you can skip as many as you'd like: background: #FF8100 url("gator.svg") no-repeat right top fixed; Is equivalent to this: background-color: #FF8100; background-image: url("gator.svg"); background-repeat: no-repeat; background-position: top right; background-attachment: fixed;

    Colors in CSS3

    CSS color module 3 now has some fun new ways to play with colors:

    RGBA

    Anything that can have a color can now also be assigned a level of alpha-transparency. The "a" in RGBA is for the alpha, and a value between 0 and 1 is expected. 0 is fully transparent and 1 is fully opaque: .shape1 { background-color: rgba(63, 35, 98, 1); } .shape2 { background-color: rgba(63, 35, 98, 0.8); } .shape3 { background-color: rgba(63, 35, 98, 0.6); } .shape4 { background-color: rgba(63, 35, 98, 0.4); } .shape5 { background-color: rgba(63, 35, 98, 0.2); } Setting an alpha value on an element is pretty cool because it won't affect child elements like the opacity attribute does. For example, if you set a div to an opacity of 0.5, everything that's inside of it will also be 50% transparent, but if you set the background color of the div to an alpha of 0.5, only the background color will be semi-transparent.

    HSL and HSLA

    HSL stands for Hue-Saturation-Luminosity. Many designers and photographers are already used to setting the values for the hue, saturation and luminosity using a software like Photoshop. You won't be creating any color that you can't get using the RGB notation, but it's simply a shortcut if you happen to find it easier to set hue, saturation and luminosity values rather than red, green and blue values. Here's a great online HSL color picker.
  • Hue: a value in degrees of the color wheel. 0 degrees is red, 120 degrees is green and 240 degrees is blue.
  • Saturation: a % value of the amount of saturation applyied to the base hue, with 100% being the full color. The closer the saturation is to 0%, the closer the color will be to a neutral gray.
  • Luminosity: a % value of the amount of darkness or lightness. Using 0% luminosity will always be black, no matter the hue and saturation, and 100% luminosity will always be white. 50% is the normal midpoint value.
  • HSLA is like RGBA, but for HSL. Simple as that! Here are two examples, the first one with varying saturation and the second one with varying luminosity: .shape1 { background-color: hsl(43, 100%, 50%); } .shape2 { background-color: hsl(43, 80%, 50%); } .shape3 { background-color: hsl(43, 60%, 50%); } .shape4 { background-color: hsl(43, 40%, 50%); } .shape5 { background-color: hsl(43, 20%, 50%); } .shape1 { background-color: hsl(43, 100%, 10%); } .shape2 { background-color: hsl(43, 100%, 30%); } .shape3 { background-color: hsl(43, 100%, 50%); } .shape4 { background-color: hsl(43, 100%, 70%); } .shape5 { background-color: hsl(43, 100%, 90%); } Browser Support Can I Use css3-colors? Data on support for the css3-colors feature across the major browsers from caniuse.com.

    currentColor

    currentColor is used like a variable and keeps a tab on which color was last used. It can be very useful in reducing the amount of edits you'd have to make to edit an element's colors: .pirate { color: hsla(310, 100%, 24%, 1); border-top: 2px solid currentColor; } .pirate p { border-right: 5px solid currentColor; }

    What's coming next…

    CSS Color Module Level 4, currently in working draft, has even more goodies for colors:
  • The color() function: borrowing the idea from CSS preprocessors like Sass and allowing you to modify the colors that you have defined as variables (yes, it looks like we'll have variables too with CSS Custom Properties level 1)
  • The hwb() function: Hue-Whiteness-Blackness, yet another way to skin the cat.
  • The gray() function: 50 shades of grey, the CSS way.
  • 4 and 8-digit HEX colors: finally also a way to specify alpha transparency with HEX colors too!
  • The CSS calc() function

    Calc() is a CSS function that lets you calculate values right in your CSS. For example: .pirate { position: absolute; /* lets have the pirate 20px from the left */ left: calc(50px - 30px); } At first glance you might think Why the heck would I care? I can just set it to 20px. Well things get interesting when you realize that you can mix and match the units: left: calc(1.5em - 8px); And things get even more interesting when you mix in percentage values. The following sets to width of the selected element to 80px less than 100%: width: calc(100% - 80px); Make sure to use spaces around the operand. For example: v1 + v2, not v1 +v2 or v1+v2. You can use calc() anywhere where you would use numeric values (e.g.: width, max-height, margin-left, …) Calc() is very useful for things like vertical centering if you know the height of the element you want to center. You just add a margin-top to the element of 50% of the viewport height minus half the height of the element. Let's say our element is 100px tall: .my-element { display:block; margin-left:auto; margin-right:auto; /* 50vh = 50% viewport height */ margin-top: calc( 50vh - 50px ); width: 200px; height: 50px; } Browser Support Can I Use calc? Data on support for the calc feature across the major browsers from caniuse.com.

    A Curated List of CSS Resources

    Below is a list of good sources of information and reference for CSS. You'll find links to websites/blogs, books and tools.

    On the web

  • CSS-Tricks - Obviously
  • Lea Verou - All of her stuff is awesome
  • Eric Meyer - The master
  • An amazing CSS reference on Codrops
  • Most web design websites focus heavily on CSS. Smashing Magazine and A List Apart are two great ones.

    Videos and screencasts

    Anything by Lea Verou:
  • The Missing Slice
  • The Humble Border-Radius
  • Colour Theory
  • CSS3 Secrets: 10 things you might not know about CSS3
  • More CSS Secrets: Another 10 things you may not know about CSS
  • Tools

  • Codepen - Obviously, again!
  • Pleeese Play - Online prefixer tool
  • CSSmatic - Nifty little tools
  • Cubiz-Bezier - Create your own easing functions
  • Front-end dev tools

    These are not just CSS tools, but tools that are helpful in general for front-end stuff (HTML, CSS, SVG, JS,…):
  • Grunt - The JavaScript task runner
  • Yeoman - The web's scaffolding tool
  • Bower - A package manager
  • Gulp - An alternative to Grunt
  • Books

  • CSS Secrets by Lea Verou - This book is the bomb. Just get it already!
  • Sass stuff

    You're taking it to the next level and taking on Sass to write your CSS? Here's a few good pointers to get started:
  • The Sass website has a great intro tutorial. That's also the right place to start if you have no idea what the heck Sass is.
  • The Sass Way - Great stuff
  • This post on Skotch.io
  • CSS Reference

    Radial Gradients

    You probably already know about CSS3's new gradients that let you avoid spending hours doing pesky photoshop tweaks…right? Well, if not, you've got some homework to catch up on. If you're all caught up with the class however, it's time to move on to a more advanced gradient, the radial gradient. It's just what it sounds like, a gradient with a radial, instead of linear flow. Picture ripples in a body of water. Or just look at the red-to-blue example below. It's usable in everything other than IE 9 and under. See the Pen Radial gradient by Alligator.io (@alligatorio) on CodePen.

    Columns

    Do you like cool, magazine style column layouts for your content? Does the thought of building a responsive table to put them in make you shudder with trepidation? Today, and everyday thereafter, for the low, low price of free you can create those nifty layouts without any messy tables or JS solutions. Just check out the example below. See the Pen CSS3 Columns by Alex Wolf (@alligatorio) on CodePen.

    Text Shadow

    It's very easy to make something look obnoxious and dated with it, but if used properly it can highlight and accentuate to a great degree. We've given you an example below that should get you started, just remember overdo at your own risks! See the Pen Text shadow by Alex Wolf (@alligatorio) on CodePen.

    Transitions

    CSS transitions are a new and exciting way to create effects without any scripting. To make this work, all you need to do is to set your element's size, and then create a rule for when you want your transition to take place, and specify a pseudo class like :hover to trigger the transition. And don't forget to specify a time in seconds for how long you want the transition to take in seconds. See the Pen CSS Transitions by Alex Wolf (@alligatorio) on CodePen.

    Fontface and WebFont

    CSS3 has opened the door for the brand new @fontface rule. This CSS rule has given rise to a powerful tool with Google's WebFonts. With it, designers can quickly search the list of WebFonts, pick one that meets their needs, and implement it easily. A standard example has been given below. Copy and paste it into your favorite text editor and then run it to see, in any modern browser, the power of WebFonts. You can go to the Google Fonts website for more fonts, or just play around with the one below. Remember, this is not and image file, so there's no extra resources used, and you can add all of your drop shadows and other text effects just like usual. See the Pen Custom fonts by Alex Wolf (@alligatorio) on CodePen.

    Text Decoration

    Text decoration is one of those things that everyone knows about but few people really leverage to its full potential. Hopefully this example below will give you some ideas, and interesting things to do with it. See the Pen Text decoration by Alex Wolf (@alligatorio) on CodePen.

    Background Attachment

    Fixed backgrounds are becoming more and more popular for things like single page, scroll based websites. And with smartphones beginning to dominate some website markets, is that really a surprise? Make sure you can keep up and understand this property, and if you need some help getting a handle on it, or just want a refresher, see the examples below.

    Single Background

    body { background-image: url("images/img.png"); background-attachment: fixed; }

    Multiple Backgrounds

    body { background-image: url("img1.png"), url("img2.png"); background-attachment: scroll, fixed; }

    Calc

    You know all of those terrible percentage hacks you have to do sometimes? You know how annoying they are? Do you wanna stop doing them? Me too. Here is a way to avoid them in the future: the calc property.Of course, this is a slightly unfinished rule, and isn't completely stable, but you can start working with it now and learn how it works. The calc() CSS function can be used anywhere a <length>, <frequency>, <angle>, <time>, <number>, or <integer> is required. With calc(), you can perform calculations to determine CSS property values. The example with syntax is below. .banner { position: absolute; left: 5%; /* for browsers without support for calc() */ left: 40px; width: 90%; /* for browsers without support for calc() */ width: calc(100% - 80px); border: solid black 1px; box-shadow: 1px 2px; background-color: yellow; padding: 6px; text-align: center; }

    CSS3: A Quick Intro

    A general overview of some of the features found in CSS3. In Web Design and Development, like most fields, you have to evolve to keep up with the times. This is especially true with new features that get added to one of a designers most often used tools, like CSS. CSS3, the latest specification for CSS, has several new features designers can start taking advantage of right now. The biggest and most important change in CSS3 is definitely the modularization of the specification approval process. What this means is that each section of CSS3 (borders, box shadow, images, etc) has its own module. That means that they can be approved individually, and developed separately. This means we get changes faster, and when they come they are more relevant to what the community and browser developers have been asking for. It also means it's easier for browser to be up to date on the new standard, because it's received piecemeal, rather than all at once. This means less worrying about how your content looks across different browsers and platforms. We all know a few in our field who are more like dinosaurs than designers. Don't be a dinosaur, stuck using outdated techniques and boring design practices. Elevate your designs and take advantage of the latest technologies with techniques like:

    Transitions

    Long have designers struggled to use Adobe Flash and JavaScript to accomplish image transitions. No more. Gone are the days of ugly, often tacky Flash transitions and difficult to implement JS animations. Now, with CSS3 transitions, designers can use a clean, lightweight browser-side solution to implement their transitions, instead of a heavy server-side method. There are two key ways to do this. First, and most simply, you can use the transition declaration and trigger mouse-based effects like hover or trigger the animation with a simple JS change. Alternatively you can use the @keyframe rule to specify specific changes to the animation that don't require user input. You can read more about CSS3 transitions here.

    Gradients

    Tired of mucking about in Photoshop, struggling to get the gradient for those buttons just right? So is everyone else. Thankfully now, you don't have to! CSS gradients allow designers to create beautiful gradients that look excellent on any display. Best of all, it's all in a nice, light-weight CSS file that's supported by all browsers, and doesn't require you to use heavy, resource taxing images (are you noticing a theme here?). Gradients have actually been around for a while now but only now are they available for use in every browser. Right now, radial and linear repeating and non-repeating gradients are available and more are likely to be on the way.

    3D Transforms

    Let's be honest for a second here. We designers can be a very…showy group of people. Some might say we enjoy lording our abilities over designers less in the know than we are. Now, if this sounds like you, or if you just want to build a beautiful, eye-catching portfolio, CSS3 3D transforms can really help your work stand out. Never ever underestimate the value of a little flash (pun shamelessly intended) in your web page design, especially when you want to stand out from a veritable sea of other designers.

    Border Radius

    Rounded corners look great. Rounded corners look natural. Rounded corners have historically been a pain in the ass to code, and using images can quickly increase file sizes. Now your buttons can have natural, rounded edges without excessive code! Use CSS3's new border-radius property to create simple rounded edges that don't require excess fiddling with height and width properties, and don't break when you tweak content or location. If you want an example, try these code snippets (courtesy of webreference.com ) on a web page of your own.

    CSS:

    .box { border: 2px solid orange; border-radius : 25px; width: 100px; padding: 10px; text-align:center; }

    HTML:

    <div class='box'>Submit</div>

    Border Image

    Continuing on the subject of borders, how often have you wanted to have a nice, pretty border around a div or image, only to realize that you have to spend time in Photoshop and even more time making the border responsive because all of your default choices are just plain unattractive? Now your borders are only limited by your imagination and Photoshop/Illustrator skill. You can now create easy to work with image sprites and apply them with the border-image property. That will let you quickly and easily create those pretty borders you want, all without spending hours fiddling and adjusting things.

    Web Fonts

    It seems like only yesterday designers were forced to consult tables and lists of “web-safe” fonts. Well, those days are behind us now, and all of us should be grateful. The @font-face rule now allows you to use services like Google Web Fonts and typekit to include any font you could possibly imagine just be incorporating a new stylesheet. This means your typography choices are no longer limited to ones you know your end-user is likely to have access to. This also means no more specifying 12 different font-family's just to be sure your text isn't an ugly default font.

    CSS Columns

    Want to layout your articles in a responsive, column based layout? Not long ago that meant you had three options. First, you could use a table and be loathed by everyone in the design world. Second, you could use JS to flow your content into containing divs and be loathed by yourself for the torturous amount of time such a process would take. Third, you could sell your soul to make a deal with the Devil and have him do the coding for you. Now however, no tables or supernatural bargains are needed! You can simply use the columns rule and you're done. The only issue you may run into is with getting things to look the same across all browsers (I'm looking at you IE) but with Internet Explorer going the way of the dodo, it looks like that issue should be sorted out as well.

    Selectors

    Finally, and perhaps most importantly, we have new CSS selectors. It would take more space than I want to use to go into detail about them all, so we'll just hit the highlights and you can check out the complete list here. We can still use the old CSS2 selectors as well, but now we have some new rules. What it comes down to is we now have the ability to select DOM elements based on what their attribute values are, instead of specifying ID's and Classes for each element. Now you can style them based simply on their attribute field.