7-uses-for-css-custom-properties

Custom properties (also known as CSS variables) allow us to store property values for re-use in our stylesheets. If you’re relatively new to them, you might wonder when you might use them over and above preprocessor variables (if indeed you use a preprocessor). I’m using custom properties a lot in my workflow these days, and thought I would collate some of the use cases here.

This isn’t an in-depth guide to how custom properties work, so if you need a primer I recommend the following resources:

Colour functions

Custom properties don’t just represent entire property values – they can be used to store partial values too. A commonly cited use case is in CSS colour functions. HSLA lends itself particularly well to custom properties, allowing us as developers an unprecedented level of control when it comes to mixing colours.

.some-element {
  background-color: hsla(
    var(--h, 120),
    var(--s, 50),
    var(--l, 50),
    var(--a, 1)
  );
}

.some-element.darker {
  --l: 20;
}

We can also do some very cool things like calculate complementary colours. This article I wrote last year is a much more in-depth guide to colour manipulation with custom properties, and Sara Soueidan has a great article on the subject too.

Shorthand properties

If you’re using a shorthand property such as animation, and you need to change one value for a different element, then writing out the whole property again can be error-prone and adds an extra burden of maintenance. Using custom properties we can adjust a single value in the shorthand property very easily:

.some-element {
  animation: var(--animationName, pulse) var(--duration 2000ms) ease-in-out
    infinite;
}

.some-element.faster {
  --duration: 500ms;
}

.some-element.shaking {
  --animationName: shake;
}

Repeated values

Suppose we have an element that has a consistent value for its top padding, but the same value for all the other sides. Writing the following could be a bit tedious, especially if we want to adjust the padding values:

.some-element {
  padding: 150px 20px 20px 20px;
}

@media (min-width: 50em) {
  padding: 150px 60px 60px 60px;
}

Using custom properties means we have just one place to adjust that padding. Even better, if it’s a standard value that’s used throughout the site then we could declare it in a variable partial, config file or our site’s design tokens.

:root {
  --pad: 20px;
}

@media (min-width: 50em) {
  :root {
    --pad: 60px;
  }
}

.some-element {
  padding: 150px var(--pad) var(--pad) var(--pad);
}

Complex calculations

Custom properties can be really handy for storing calculated values (from the calc() function), which themselves can even be calculated from other custom properties. One example is calculating complementary colours, as mentioned earlier. Another is when you want to calculate the inverse of a property. I wrote an article for CSS Tricks a little while ago on calculating the reverse of an easing curve with custom properties.

I often use custom properties with clip-path if I need to calculate a path relative to another, or relative to known variables. The following code from a recent demo calculates the clip path points for two pseudo elements to give the appearance of an element being bisected.

.element {
  --top: 20%;
  --bottom: 80%;
  --gap: 1rem;
  --offset: calc(var(--gap) / 2);
}

.element::before {
  clip-path: polygon(
    calc(var(--top)   var(--offset)) 0,
    100% 0,
    100% 100%,
    calc(var(--bottom)   var(--offset)) 100%
  );
}

.element::after {
  clip-path: polygon(
    calc(var(--top) - var(--offset)) 0,
    calc(var(--bottom) - var(--offset)) 100%,
    0 100%,
    0 0
  );
}

Staggered animations

If we want to stagger animations for a number of child elements, we can elegantly set the animation-delay on each one by simply defining the custom property as the element’s index:

.element {
  --delay: calc(var(--i, 0) * 500ms);
  animation: fadeIn 1000ms var(--delay, 0ms);
}

.element:nth-child(2) {
  --i: 2;
}

.element:nth-child(3) {
  --i: 3;
}

See the Pen
Staggered animation with custom properties
by Michelle Barker (@michellebarker)
on CodePen.

Unfortunately we currently have to assign the variable explicitly, which could be a problem if we have an indeterminate number of children. Splitting JS is a great Javascript library that takes care of that by assigning the element’s index as a variable, and is very useful for this kind of staggered animation. But it would be great not to have to use JS!

Adam Argyle has recently submitted a proposal for two new CSS functions, sibling-count() and sibling-index(), which would be a game-changer, making a whole lot of new things possible with CSS. They’re nowhere close to being adopted by any browsers at this point, but it would be an incredibly powerful addition, so one to keep an eye on.

Responsive grids

I’ve written about it on this blog before, but custom properties can help make complex Grid layouts easier to manage. Suppose we have an 8-column grid, which we want to change to a 12-column grid at a specific breakpoint:

:root {
  --noOfColumns: 8;
}

@media (min-width: 60em) {
  :root {
    --noOfColumns: 12;
  }
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--noOfColumns), 1fr);
}

We don’t need to write the entire property value whenever we want to update the number of columns – we could use custom properties. This is a relatively simple example, but it might be much more useful if we have a more complex grid. And the technique could apply to things like track size or item placement too.

Vendor prefixes

Some properties (like clip-path) still require vendor prefixes in some browsers – although thankfully that number is going down. If you need to write a vendor prefix and then you want to change the property value, you need to make sure you change it on the prefixed property too. With custom properties we could instead write:

.some-element {
  --clip: polygon(0 0, 100% 0, 50% 100%, 0 100%);

  -webkit-clip-path: var(--clip);
  clip-path: var(--clip);
}

Now we only have one place we need to change it.

Conclusion

These are far from the only uses for custom properties, but they’re one that I typically find myself reaching for within my workflow, and can help make your code more efficient and maintainable. No doubt you’ll discover plenty more uses of your own!

Unlike SASS variables, CSS Custom Properties can be modified in class selectors, allowing you to create abstractions and reduce the size of your CSS.

Let me show you an example!

In the CodyHouse Framework, we use the .grid-gap-{size} utility classes to set the spacing among grid items:

.grid {
  display: flex;
  flex-wrap: wrap;

  > * {
    flex-basis: 100%;
  }
}

.grid-gap-xxxs {
  margin-bottom: calc(-1 * var(--space-xxxs));
  margin-left: calc(-1 * var(--space-xxxs));

  > * {
    margin-bottom: var(--space-xxxs);
    margin-left: calc(var(--space-xxxs));
  }
}

.grid-gap-xxs {
  margin-bottom: calc(-1 * var(--space-xxs));
  margin-left: calc(-1 * var(--space-xxs));

  > * {
    margin-bottom: var(--space-xxs);
    margin-left: calc(var(--space-xxs));
  }
}

.grid-gap-xs {
  margin-bottom: calc(-1 * var(--space-xs));
  margin-left: calc(-1 * var(--space-xs));

  > * {
    margin-bottom: var(--space-xs);
    margin-left: calc(var(--space-xs));
  }
}

.grid-gap-sm {
  margin-bottom: calc(-1 * var(--space-sm));
  margin-left: calc(-1 * var(--space-sm));

  > * {
    margin-bottom: var(--space-sm);
    margin-left: calc(var(--space-sm));
  }
}

.grid-gap-md {
  margin-bottom: calc(-1 * var(--space-md));
  margin-left: calc(-1 * var(--space-md));

  > * {
    margin-bottom: var(--space-md);
    margin-left: calc(var(--space-md));
  }
}

.grid-gap-lg {
  margin-bottom: calc(-1 * var(--space-lg));
  margin-left: calc(-1 * var(--space-lg));

  > * {
    margin-bottom: var(--space-lg);
    margin-left: calc(var(--space-lg));
  }
}

.grid-gap-xl {
  margin-bottom: calc(-1 * var(--space-xl));
  margin-left: calc(-1 * var(--space-xl));

  > * {
    margin-bottom: var(--space-xl);
    margin-left: calc(var(--space-xl));
  }
}

.grid-gap-xxl {
  margin-bottom: calc(-1 * var(--space-xxl));
  margin-left: calc(-1 * var(--space-xxl));

  > * {
    margin-bottom: var(--space-xxl);
    margin-left: calc(var(--space-xxl));
  }
}

.grid-gap-xxxl {
  margin-bottom: calc(-1 * var(--space-xxxl));
  margin-left: calc(-1 * var(--space-xxxl));

  > * {
    margin-bottom: var(--space-xxxl);
    margin-left: calc(var(--space-xxxl));
  }
}

Because there’s a lot of repetition, a few weeks ago, we’ve decided to use CSS custom properties to simplify these classes.

The first step was creating an abstraction that contains the code we repeat for each utility class:

[class*="grid-gap"] {
  margin-bottom: calc(-1 * var(--grid-gap, 1em));
  margin-left: calc(-1 * var(--grid-gap, 1em));

  > * { 
    margin-bottom: var(--grid-gap, 1em); 
    margin-left: var(--grid-gap, 1em);
  }
}

This attribute selector looks for classes that contain the “grid-gap” string (all the grid-gap utility classes). Note that we’ve replaced the --space-unit variables with a new --grid-gap variable.

In our .grid class, we set the --grid-gap variable equal to 0 (default value).

.grid {
  --grid-gap: 0px;
  display: flex;
  flex-wrap: wrap;

  > * {
    flex-basis: 100%;
  }
}

Now we can modify, for example, the .grid-gap-xxxxs class as the following:

.grid-gap-xxxxs { --grid-gap: var(--space-xxxxs); }

We no longer need all the chunk of code about margins; we can just modify the value of the --grid-gap variable.

If we do the same for all the utility classes, we end up with the following:

.grid {
  --grid-gap: 0px;
  display: flex;
  flex-wrap: wrap;

  > * {
    flex-basis: 100%;
  }
}

[class*="grid-gap"] {
  margin-bottom: calc(-1 * var(--grid-gap, 1em));
  margin-left: calc(-1 * var(--grid-gap, 1em));

  > * { 
    margin-bottom: var(--grid-gap, 1em); 
    margin-left: var(--grid-gap, 1em);
  }
}

.grid-gap-xxxxs { --grid-gap: var(--space-xxxxs); }
.grid-gap-xxxs  { --grid-gap: var(--space-xxxs); }
.grid-gap-xxs   { --grid-gap: var(--space-xxs); }
.grid-gap-xs    { --grid-gap: var(--space-xs); }
.grid-gap-sm    { --grid-gap: var(--space-sm); }
.grid-gap-md    { --grid-gap: var(--space-md); }
.grid-gap-lg    { --grid-gap: var(--space-lg); }
.grid-gap-xl    { --grid-gap: var(--space-xl); }
.grid-gap-xxl   { --grid-gap: var(--space-xxl); }
.grid-gap-xxxl  { --grid-gap: var(--space-xxxl); }
.grid-gap-xxxxl { --grid-gap: var(--space-xxxxl); }

This optimization reduces the CSS size of this example by more than half! Obviously, you can apply this technique only when it’s possible to abstract some rules (I’m not suggesting that CSS custom properties will reduce by half the size of your CSS). But still, this tutorial is just an example of code optimization made possible by using CSS variables.

ps: CSS Variables are supported in all modern browsers.

If you’re interested in learning more about our grid system, download our framework or check the Grid and Layout page of the docs.

Be the first to know when we ship something cool!

creating-a-custom-focus-style

9th Oct 2019

When you create a custom focus style, you want to think about four things:

  1. Adding an outline
  2. Creating animations that contain movement
  3. Changing the background color
  4. Changing the text color

I wrote more about this in my article on designing focus. During my research, I found three kinds of focus style I liked.

  1. The one on Smashing Magazine
  2. The one on WTF Forms
  3. The one on Slack
Focus styles on Smashing Mag, WTF Forms and Slack

Today, I want to show you how to create these focus styles and use them effortlessly across your website.

Creating the focus for Smashing Magazine

Smashing Magazine uses a large dotted outline for focus. To create this focus style, you set the outline property to 3px dotted.

Focus styles on Smashing Magazine.
*:focus {
  outline: 3px dotted #761b15;
}

See the Pen
Focus style Smashing Mag (default)
by Zell Liew (@zellwk)
on CodePen.

If you want to change the color of the outline, you can change the outline-color property.

.red-background *:focus {
  outline-color: white;
}

See the Pen
Focus style Smashing Mag (changing outline colors)
by Zell Liew (@zellwk)
on CodePen.

Alternatively, you can use CSS Variables.

:root {
  --outline-color: #761b15;
}

*:focus {
  outline: 3px dotted var(--outline-color);
}

.red-background {
  --outline-color: white;
}

See the Pen
Focus style Smashing Mag (with CSS Variables)
by Zell Liew (@zellwk)
on CodePen.

Creating focus styles for WTF Forms

The focus style for WTF forms contains two parts:

  1. A white border
  2. A blue border
Focus styles for WTF Forms.

This style can be created with box-shadow. The idea is you create two shadows:

  1. The first shadow with the background’s color
  2. The second shadow with the focus’s color
*:focus {
  outline: none;
  box-shadow: 0 0 0 .075rem #fff, 
              0 0 0 .2rem #0069d4;  
}

If you want to change the focus color, you need to rewrite the entire box-shadow.

.blue-background *:focus {
  outline: none;
  box-shadow: 0 0 0 .075rem #0069d4, 
              0 0 0 .2rem #fff;  
}

Note: WTF Forms does not have styles for links and buttons. Only form elements. It doesn’t have styles for a darker background either. I created this demo according to what I thought looks okay.

See the Pen
WTF Forms focus style
by Zell Liew (@zellwk)
on CodePen.

There’s an easier way. If you used CSS variables, you only need to switch the colors.

:root {
  --focus-inner-color: #fff;
  --focus-outer-color: #0069d4;
}

*:focus {
  outline: none;
  box-shadow: 0 0 0 .075rem var(--focus-inner-color), 
              0 0 0 .2rem var(--focus-outer-color);
}

.blue-background {
  --focus-inner-color: #0069d4;
  --focus-outer-color: #fff;
}

See the Pen
WTF Forms focus style (with CSS Variables)
by Zell Liew (@zellwk)
on CodePen.

Creating focus styles for Slack

The focus style on Slack contains two parts:

  1. A dark blue outline
  2. A light-blue border
Focus styles on Slack.

This focus style can be created with the same technique as WTF Forms.

*:focus {
  outline: none;
  box-shadow: 0 0 0 2px hsla(210, 52%, 42%, 1.00), 
              0 0 0 .6rem hsla(200, 72%, 83%, 0.75);
}

The CSS Variables trick works wonders if you need to change colors.

:root {
  --focus-inner-color: hsla(210, 52%, 42%, 1.00);
  --focus-outer-color: hsla(200, 72%, 83%, 0.75);
}

*:focus {
  outline: none;
  box-shadow: 0 0 0 2px var(--focus-inner-color), 
              0 0 0 .6rem var(--focus-outer-color);
}

.dark {
  --focus-inner-color: hsla(0, 0%, 100%, 0.75);
  --focus-outer-color: hsla(0, 0%, 100%, 0.25);
}

See the Pen
Slack Forms focus style (with CSS Variables)
by Zell Liew (@zellwk)
on CodePen.

If you use this technique on elements with borders, you might want to remove the borders. It’s not pretty to see two stacking borders.

button:focus {
  border-color: transparent;
}

See the Pen
Slack Forms focus style (improved border)
by Zell Liew (@zellwk)
on CodePen.

Combined demo

I combined the different methods onto one demo for you to play with. Here it is:

See the Pen
Focus style
by Zell Liew (@zellwk)
on CodePen.

Thanks for reading. Did this article help you out? If it did, I hope you consider sharing it. You might help someone else out. Thanks so much!

custom-thumbnails-in-figma

Custom thumbnail of the DockYard logo created with Figma, a collaborative design tool

Figma is a great tool for collaborative design and handoff, but at the time of publishing this post, Figma automatically selects the cover or project thumbnail for each project.

4 projects in Figma

As the number of projects in your team increases, the more difficult it is to differentiate between the things you are trying to find. The solution? Create custom thumbnails for your Figma projects.

How to customize Figma thumbnails

Create a new Page in your project and name it ‘Figma Cover Image.’ If you have multiple pages, make sure you change the order so it is the first page in the list:

A text list of Pages in the Figma project, with the Figma Cover Image at the top

Figma project thumbnails change width depending on the size of your Figma window. To get an edge-to-edge thumbnail, create a 620 by 320 pixel Frame and remove the background color (hit the ‘—’ in the Background attribute in the right sidebar). This makes the Frame transparent, so you will need to set the background color of the entire canvas by selecting the Frame and using the Background setting at the top of the Design panel on the right.

Using the color picker to change the background color of the canvas

Now that we have the background defined, we can start adding artwork to the Frame. Work as you would with any other Figma project. Just make sure any text or images are large enough to be legible in the project view, and you are good to go.

The DockYard logo and text reading 'DockYard Colors' below

Depending on the size of the Figma project, it may take a few minutes for your thumbnail in the project to refresh and display in the Projects screen. Once it has propagated, you should have an edge-to-edge thumbnail that makes your project stand out and, as a bonus, even easier to find.

The same 4 Figma projects but with an updated thumbnail for DockYard Colors

TL;DR

If you’re looking for a quick primer on customizing your project thumbnail, look no further than this handy step-by-step list:

  1. Create a Page and make sure it is at the top of the pages list.
  2. Draw a 620 by 320 pixel Frame and remove the background of the frame.
  3. Deselect the frame and change the background color of the canvas to get an edge-to-edge thumbnail.
  4. Add the artwork to the Frame.
  5. Wait for the updates to propagate to the Projects screen.

Have fun wowing your collaborators by customizing your project thumbnails in Figma, and please share your creative thumbnails with me on Twitter.

DockYard is a digital product agency offering custom software, mobile, and web application development consulting. We provide exceptional professional services in strategy, user experience, design, and full stack engineering using Ember.js and Elixir. With a nationwide staff, we’ve got consultants in key markets across the United States, including Seattle, Los Angeles, Denver, Chicago, Austin, New York, and Boston.

Subscribe to our newsletter for more great content like this

top-10-css-custom-scroll-bars

CSS Custom Scroll Bar

Latest Collection of hand-picked CSS Custom Scroll Bar code examples.

1. Hide scroll bar Cross-browser

CSS Custom Scroll Bar

demo and code

2. Custom Scroll Bar for Chrome

demo and code

3. AngularJS Directive: Scroll bar on top and bottom of div

Made with

  • HTML / CSS / JS

demo and code

4. Horizontal Scroll with out the scroll bar

Made with

  • HTML / CSS / JS

demo and code

5. Scroll Bar Fix

Made with

  • HTML / CSS(SCSS)

demo and code

6. Webkit scrollbars

CSS Custom Scroll Bar

demo and code

7. Scroll bar manipulation

Made with

  • HTML / CSS / JS

demo and code

8. Scroll Position Indicators

Made with

  • HTML / CSS / JS

demo and code

9. CSS Scroll Bars

demo and code

10. Fade in and out scroll bar on div hover

demo and code