CSS Properties Memory Test

Remember that HTML Tags Memory Test from before? Šime Vidas recently joked that a similar Memory Test but for CSS Properties should exist.

Of course I couldn’t resist, so here is the CSS Properties Memory Test 🤪


See the Pen CSS Properties Memory Test by Bramus (@bramus) on CodePen.

In total there are 653 properties for you to guess. Good luck! 😅

~

# Behind the scenes

The demo itself is a straight up fork from the aforementioned HTML Tags Memory Test with an adjusted list of items to guess and a small style change to tweak the appearance of the already guessed results.

The list of itself properties was generated from the “Properties and Descriptors” CSS Index. The index lists 705 properties, but I’ve filtered out -webkit-prefixed properties that also exist without such a prefix. The filtered array was eventually converted to a string and base64 encoded to discourage cheating.

// Get all listed properties
const allProps = $$('#properties + div > ul.index > li').map(($li) => $li.textContent.trim().split("\n")[0]); // ~> 705 props

// Filter out -webkit prefixed props that also exist without a prefix
const filteredProps = allProps.filter(prop => !(prop.startsWith('-webkit-') && allProps.includes(prop.replace('-webkit-', '')))); // ~> 650 props

// Base64 encode the whole lot string to discourage cheating ;)
const encodedProps = btoa(filteredProps.join(','));

Note that when decoded again there are 653 properties to guess. That’s because one of the entries lists 4 properties separated by a comma.

~

🔥 Like what you see? Want to stay in the loop? Here's how:

Responsible Web Applications

Good little collection of tips for creating responsible (= responsive + accessible) web applications by Joy Heron.

With modern HTML and CSS, we can create responsive and accessible web apps with relative ease. In my years of doing software development, I have learned some HTML and CSS tips and tricks, and I want to present these in this post. This list is not exhaustive, but these are tried and true patterns that I frequently use in different projects.

A shame she calls them “tips and tricks though, as there for example is no “trick” to using proper headings and landmarks — It is a basic idea/pattern every frontend dev should know about and apply, no magic needed.

Responsible Web Applications →

Sidenote: You might want to refrain from using the <details> as an accordion though …

Guide to Advanced CSS Selectors

Two part series by Stephanie Eckles on CSS Selectors

In this two-part mini-series, we’ll explore some of the more advanced CSS selectors, and examples of when to use them.

Even if you’re doing frontend but not primarily writing CSS you should learn these, along with the basic CSS vocabulary.

This knowledge will allow you read code that others have written both today and tomorrow, when then framework-du-jour is long gone.

Guide to Advanced CSS Selectors – Part One →
Guide to Advanced CSS Selectors – Part Two →

The complete guide to CSS media queries

Last summer Kilian Valkhof did a wonderful write-up on the Polypane blog covering CSS Media Queries.

Media queries are what make modern responsive design possible. With them you can set different styling based on things like a users screen size, device capabilities or user preferences. But how do they work, which ones are there and which ones should you use?

Good for beginners, but seasoned developers might also want to take a look at the “New notations in Media query levels 4 and 5” section 😉

The complete guide to CSS media queries →

CSS Sticky Parallax Sections Demo

Nice demo on CodePen by Ryan Mulligan, featuring some sections with a sticky parallax background image:

See the Pen CSS Sticky Parallax Sections by Ryan Mulligan (@hexagoncircle) on CodePen.

I expected to find the the translateZ() + scale() method to create the parallax layers in there, but turns out Ryan took another approach:

  1. Scale down each enclosing section, using a scaleY transform with a number lower than 1, e.g. scaleY(0.9)
  2. Scale up each contained direct child of those sections using an inverse scaleY transform, e.g. scaleY(1.11111111)

As the second scaling (1.11111) undoes the first scaling (0.9), the content is rendered at the original scale of 1 again (e.g. 0.9 * 1.11111 = 1).

:root {
  --speed: 0.1;
}

.section {
  transform-origin: center top;
  transform: scaleY(calc(1 - var(--speed)));
}

.section > * {
  transform-origin: center top;
  transform: scaleY(calc(1 / (1 - var(--speed))));
}

Note that I’ve renamed Ryan’s --scale parameter to --speed here, as that’s what it affects.

Using Emoji as the Mouse Cursor on a Webpage

Recently I saw this tweet by Marco Denic fly by:

To use an emoji as the cursor you can’t simply type in the emoji though.

/* ❌ This won't work */
html {
	cursor: 👻, auto;
}

What you’ll have to do instead is embed the emoji inside an SVG and then successively embed that SVG in the CSS file by passing it as a Data URL into the url() function.

/* ✅ This will work */
html {
	cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="64" width="64"><text y="28" font-size="32">👻</text><path d="M0,2 L0,0 L2,0" fill="red" /></svg>'), auto;
}

See the Pen
Emoji Cursor
by Bramus (@bramus)
on CodePen.

I’ve also added a little triangle in the top left corner of the SVG, as that’s where the actual tip of the pointer is. Omitting it makes up for a really weird experience.

If you’re on a device that does not show a pointer, here’s a recording of what the demo looks like:

To customize the color of the tip you can change its fill value to any color you like. Although not recommended you can remove the entire <path> if you don’t want it.

To change the overall size of the emoji cursor, change the height and width attributes of the SVG. Best is to leave the other attributes (such as viewBox and font-size) alone, as those have been carefully tweaked.

🔥 Using this same technique you can set an emoji as the favicon.

~

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

Smooth Scrolling and Find In Page, a not so Smooth Combination …

There was this interesting Twitter conversation last week between Chris Coyier and Schepp last week. Apparently if you have Smooth Scrolling enabled, it also affects the behavior of Find in Page in Chrome: Whenever you want to go to the next result it will smooth scroll, instead of jump to it.

Schepp chimed in and offered the solution: leverage the :focus-within pseudo-class selector so that it’s only applied when the html has focus.

Combine it with prefers-reduced-motion and you’ll end up with this:

@media(prefers-reduced-motion: no-preference) {
    html:focus-within {
        scroll-behavior: smooth;
    }
}

There’s on nasty side-effect though: in-page jump links that refer to the id of an element will no longer work. You’ll actually need to sprinkle some <a name="…">#</a> elements over your markup to make those work smoothly …

Fixing Smooth Scrolling & Page Search →
Chromium Bug #866694 →

CSS mix-blend-mode not working? Set a background-color!

💡 If you find your CSS mix-blend-mode not working as expected (on a white background), you need to explicitly set a background-color on the underlying element. The easiest way to do so is to apply background-color: white; on the html and body elements.

html, body {
    background-color: #fff;
}

~

Demos + Explanation

Without a background-color set

You’ll notice here that for the “white” sections, the set mix-blend-mode: difference does not seem to work. The navigation will stay white and visually blend into the white background. Note that the navigation is not actually gone, as you can still see it shine through whenever a number of any of the sections crosses it.

See the Pen CSS mix-blend-mode not working? (1/2) by Bramus (@bramus) on CodePen.

The reason why it doesn’t work is that the white sections don’t really have a white background. They have no background-color set, so they fall back to the default value of transparent. Visually this is manifested as a white color, but to the compositor it will still be transparent. As the compositor can’t calculate the difference of the white text against the transparent background, the text will remain white.

~

With a background-color set

With background-color: #fff; set on the body/html the compositor does know how to calc the difference, and the demo will behave correctly.


See the Pen CSS mix-blend-mode not working? (2/2) by Bramus (@bramus) on CodePen.

Alternatively we could set this declaration on the sections themselves:

section {
    background-color: #fff;
}

~

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

Nested Media Queries

I can’t seem to find any mention of this in the Media Queries Module specification, but apparently it’s allowed to nest media queries, as shared by Šime Vidas:

That’s … awesome! 🤯

Fiddling with it a bit more, turns out this snippet also works as expected:

@media not print {
  @media (min-width: 0) {
    p {
      font-weight: bold;
    }
    @media (max-width: 750px) {
      p {
        background: yellow;
      }
    }
  }
}

You can play with this CodePen demo to try it yourself.

UPDATE: Thanks to reader Videm Makeev for pointing out that support for nested @media blocks was added to Opera 12.50 back in 2012! Its syntax is defined in the CSS Conditional Rules Module specification.

The Art of Building Real-life Components

Ahmad Shadeed sweats the details to recreating the little component above, as found in Facebook’s Messenger.

In this article, I will show you a component that looks simple from the first glance, but there is a ton of work behind it.

As you can derive from the article’s length: the devil is in the details. You can get to a basic result really quickly, but most of your time will go to making it resilient, supporting RTL, implementing all variants, supporting Dark Mode, …

The Art of Building Real-life Components →