Today I Learned

A Hashrocket project

19 posts about #html-css

CSS :root Selector

Assign styles to the root, <html> element by assigning them to a :root style block:

:root {
  background: red;

Now, when you open up your web page, you'll see that the <html> element has a red background! Preeetty cool right?!

CSS Variables

CSS3 supports native variables that are assigned with the following syntax:

html {
  --foo-color: #FF0000;
  --bar-color: #00FF00;

Note the -- that precedes the variable's name. Now, the <html> element and all its descendants will be able to access the variables with the following syntax.

a {
  color: var(--foo-color);

button {
  background: var(--bar-color);

CSS uses the var function to look up variables.

You don't have to assign the variable to the <html> tag. It can be assigned to any element or selector's style block. Just remember, only that element and its children will have access to the variable ;-)

Futhermore, you can access the variables in Chrome's DevTool/Element Inspector!

NOTE: This feature is not supported at all in Internet Explorer and only has partial support in Microsoft Edge 15, the most recent Edge at this time of writing. Opera Mini users are out of luck as well :-(

Browser Support Chart

rel attribute for performance and security

The rel attribute on HTML links need to be set to noopener if you're using target=_blank in your links, otherwise the new tab contains a reference to the other tab's window object, and can redirect, manipulate dom, etc.

Read more and see a demo here:

There are also some performance benefits:

Chrome Developer Tools Undo

A really nice feature of Chrome Developer tools is undo. It's the standard ⌘ + Z on a Mac, allowing you to walk back your changes in the Elements editor, like so.

Great for HTML and CSS experimentation.

Spellcheck Attribute

Have you ever noticed formatting like this in a text field?

The browser knows that 'Today' and 'Learned' are misspelled... but how?

The answer is the spellcheck attribute. Set it to true to enable the spellcheck magic. Right click each word for suggestions, dictionaries, etc. (Chrome).

Spellcheck is enabled by default on Chrome, but you will have to set it explicitly on some or all versions of Firefox and IE. Learn more here:

Create a Placeholder for Content Editable Divs

When you have a content editable div. Add an data attribute. We're going to use placeholder:

<div contenteditable="true" data-placeholder="(untitled)" class="title">

Then in your css, use a few pseudo classes to make it behave like a placholder:

.title:empty:not(:focus):before {
  content: attr(data-placeholder)

Very cool! I (for whatever reason) never knew about :empty, :not, attr() or chaining multiple pseudo classes. Learned a lot in this little snippet :)

h/t @alejandroRINC0N

Break long strings nicely with <wbr>

Are super-long strings (typically URLs) breaking out of an otherwise narrow column of text in your design? Sprinkle in some <wbr> tags; they don't take up any space, but provide the browser with safe places to break the string to a new line.

For example, this super-long URL will look normal, but if it's in a narrow area it'll linebreak at any of the <wbr> points:

<a href="">

Learn all about the <wbr> at MDN.

Frontmatter Date Affects Build

Middleman is an excellent choice for blogging. Combined with Frontmatter, we can do many things.

Today I learned that if you include a future date key in your Frontmatter, the file in question will be excluded from the build.

And so, today, this file would not be built with middleman build:

<!-- source/episodes/1/first_episode.html.markdown -->
date: 06-21-2016

This makes sense, but it was not intuitive to me and took some troubleshooting.

The `<picture>` element is here to stay!

Safari 9.1 has officially added support for the <picture> element, allowing you to specify multiple image resources per viewport size. Now that Chrome and Safari both support it, go nuts (as long as you don't need to support IE).

    <source media="(min-width: 1000px)" srcset="picture_large.jpg">
    <source media="(min-width: 500px)" srcset="picture_small.jpg">
    <img src="picture_default.jpg">

Read more about it in the release notes!

Use `percentage()` instead of percentages in Sass

Instead of writing out stuff like width: 66.667% for an element, let Sass take care of it for you with percentage:

.thirds {
  width: percentage(1/3);

.two-thirds {
  width: percentage(2/3);

Max out your `vw` with Sass

A pretty big downside to vw units is that they are relative to the viewport width, regardless of the maximum width of your site itself. So if the user fullscreens your site on a big monitor, your vws will be huge while the rest of your site stops growing at some reasonable width. Here's a handy Sass mixin to address that problem.

@mixin max-vw($attr, $value) {
  #{$attr}: #{$value}vw;
  @media screen and (min-width: 1400px) {
    #{$attr}: ($value/100) * 1400px;

Basically, since 1 vw is 1% of the viewport width, at a certain max breakpoint, we use an equivalent percentage of the max site width instead.

For example, this will assign a font-size of 10vw, but after the viewport enlarges past 1400px, the font-size will then set to a static 140px (10% of 1400px):

.foo {
  @include max-vw(font-size, 10)

HTML in Markdown

Today I learned that you can add raw HTML directly into a Markdown file.

This realization came when trying to include an image in a blog post. I started out by linking to the image with standard Markdown syntax:


But later realized I wanted to include a responsive Bootstrap class on the image, which I did with raw HTML:

<img src="" class="img-responsive" alt="Image">

It's pretty cool that you can do both— Markdown syntax gets processed into HTML, but raw HTML can be used as well.

Don't forget whitespace for `calc()`

When using the CSS calc() property, don't forget whitespace around the operator. This will mysteriously fail:

.foo {
  min-width: calc(100%-8rem)

This will parse correctly:

.foo {
  min-width: calc(100% - 8rem)

Animate with Transforms for Great CPU Success

I'm currently animating a bunch of clouds across a sky, for a thing, doesn't matter. I was previously animating with:

@keyframes cloud {
  0% {
    margin-left: 100vw;
  100% {
    margin-left: -30vw;

10 clouds ate about 70-75% of my CPU. When I switched to transform instead, my CPU usage dropped to about 20%:

@keyframes cloud {
  0% {
    transform: translateX(100vw);
  100% {
    transform: translateX(-30vw);

So: animate with transforms whenever possible to save the planet.

Protocol-relative URLs are now discouraged

For a long time, I've used protocol-relative URLs as a way to serve assets from a page using the same protocol (i.e. http or https) as the parent page. They look like this:

<img src="//"/>

But now that SSL is encouraged everywhere on the web, one should always use https when an asset supports it.

<img src=""/>

According to Paul Irish, It’s always safe to request HTTPS assets even if your site is on HTTP, however the reverse is not true.

Smarter CSS positioning with calc()

Let's talk a specific use case: if you're looking to position something a fixed amount from the bottom edge of an area, you'll end up with something like this:

.foo {
  position: absolute;
  top: 100%;

... but if you want the element to be offset a fixed amount from the bottom edge, the standard methodology used to be to just add some margin:

.foo {
  position: absolute;
  top: 100%;
  margin-top: 10px;

However, with calc(), you can just throw a fixed amount onto your percentage:

.foo {
  top: calc(100% + 5px)

There are countless other uses, but for me that's the one that comes up the most, so there you go. As always, check for browser caveats (you're basically safe everywhere except <IE10).


If you haven't used CSS viewport units like vw and vh yet, you're missing out on some really fun ways to solve responsive problems. A vw and a vh are equal to 1% of the viewport width and height, respectively.

  • use vw for padding to scale your padding responsively without having to use @media breakpoints
  • set a font-size in vw to allow fonts to scale with the viewport (the TODAY I LEARNED page heading is set using vw)
  • use vw for box-shadow to let your box-shadows scale down with the page (also a feature of the TIL site)

For more sweet viewport unit tricks, check out Rye Mason's post on the Hashrocket blog.

Generating subclasses with Sass Maps

Say you have a set of colors that correspond to class names:

$category-colors: (
  "bananas": "yellow",
  "oranges": "orange",
  "blue-milk": "cyan",
  "cabbage": "lime",
  "sour-warheads": "magenta"

And sometimes those class names recolor a background, but sometimes they might override something else, like a border or text color. Try this mixin on for size:

@mixin category-colors($attr:color)
  @each $class, $color in $category-colors
      #{$attr}: #{$color}

So this call will output subclasses of .widget.bananas, etc., each with the appropriate text color ...

  @include category-colors

And this one will output subclasses with the appropriate background color (or whatever other attribute you'd like).

  @include category-colors(background-color)

Date Input Tag

The HTML date input tag allows you to request dates in a web form.

<input type="date">

This tag is more semantic for date input than text, and provides a side benefit: Google Chrome will automatically display a calendar selector on the page.