Today I Learned

hashrocket A Hashrocket project

72 posts about #html-css surprise

`border-collapse` to collapse borders

There are two settings for the css property border-collapse, separate and collapse. Table cells and the table itself can both have borders. If the value separate is set, then each cell has its own border, with the space in between the borders governed by the border-spacing property.

If collapse is set, then the table cells and the surrounding table will share the borders surrounding them.

Refresh A Twitter Summary Card Image

Twitter provides a feature called summary card images: if you’ve ever seen a tweet with a rectangular image included, that’s it. We can specify this image via HTML meta tags. Most tweets from the @hashrocketil follow this pattern.

Changing the image is tricky, however, because Twitter caches summary cards for an unknown amount of time (I’ve read one week). Which means past and future Tweets could include an outdated image for a while.

One solution is to use Twitter’s card validator on your site. Running the site it through the validator seems to refresh the cache for your summary cards.

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 element and all its descendants will be able to access the variables with the following syntax. ```css 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 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:

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:

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 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 points:

Learn all about the `` 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:

date: 06-21-2016

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

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:


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

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:

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

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


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)