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!

10-hidden-css3-properties-you-should-know

CSS3 have made designing web more exciting with the introduction of new properties. While you might know of the popular ones, such as the box-shadow, border-radius, and transform, there are plenty more properties that you may not have heard of or tried, but would be glad to know of its existence.

W3C is constantly working on new CSS properties to make the web much better for designers, developers and users. In the meantime, let’s take a look at these 10 properties you may not know of but should really check out.

Recommended Reading: Beginner’s Guide to All Things CSS3

1. Tab Size

Most code editors are equipped with Tab Size control that allows developers to specify the code indentation width made with the Tab key. It was only recently that we were also able to customize the indentation of the code embedded on webpages.

pre {
	tab-size: 2;
}

Note that each browser may have their own interpretation of how long the tab-width unit should be. So, we may expect to see some discrepancies among different browsers. In terms of browser support, the tab-size property works in Chrome, Opera, Firefox, and Safari according to CanIUse.

tab size

2. Text Rendering

The text-rendering property will tell browsers how they should render the text within webpages. The text will be optimized for performance, legibility, or precision, which will eventually determine the text quality. Take a closer look at the kerning of the text in the following screenshot for a comparison between ‘normal’ text and optimizedLegibility text:

rendering size
IMAGE: AestheticallyLoyal

For more advice on good typography, check out Practical Typography.

3. Font Stretch

Some fonts provide additional faces aside from the regular Normal, Bold and Italic. Helvetica Neue or Myriad Pro as an example comes with faces such ‘Condensed’, ‘Ultra-condensed’, and ‘Semi-condensed’. This is where a new property called font-stretch is introduced; it allows us to apply these faces.

normal condensed

We may use font-stretch in conjunction with font property like for instance,font-style. Here is an example:

h1 {
	font-style: bold;
	font-stretch: ;
}

The font-stretch property currently only works in Firefox and Internet Explorer 9 (and above).

4. Text Overflow

The text-overflow property specifies presentation of content that is overflowing or truncated by its container. The default value is set to clip which simply hides the truncated text. Alternately, you can set it to ellipsis to depict the truncated text or content with horizontal ellipsis, as follows.

.content-box {
	text-overflow
}

In case you are wondering, horizontal ellipsis is the three dots at the end which usually indicates omitted content.

text overflow

5. Writing Mode

Not every language is written from the left to right direction. A few languages are instead written from top to bottom like Japanese or right to left like Arabic and Hebrew.

writing mode
IMAGE: AimiriFont

To accommodate these languages, a new property named writing-mode is introduced to let developers change the content writing direction through CSS. This code snippet, as an example, directs the content flow from the left to the right (regardless of the language).

p {
	writing-mode: rl-tb;
}

To change the flow of content, moving from top to bottom, set the property with the vertical-lr value:

p {
	writing-mode: vertical-lr;
}

6. Pointer Events

The pointer-events property allows us to control element behavior under pointer events like dragging, hovering and clicking. Using this, the affected link will do nothing when it is clicked; the link will be completely disabled, and will not even direct users to the address specified in the href attribute.

a {
	pointer-events: none;
}

Due to some critical issues however the pointer-events property is put on hold until the next CSS revision, CSS4.

7. Image Orientation

In an image editor such as Photoshop, you can change the image orientation by rotating or flipping the image. Now CSS3 allows you to do the same to the images on webpages through a new property called image-orientation. Here is an example on how we can flip an image horizontally using this property.

img {
	image-orientation: flip;	
}

You can also retain the original image orientation by specifying the property value to from-image, like so.

img {
	image-orientation: from-image;
}

8. Image Rendering

Similar to the text-rendering property, image-rendering defines the image quality on webpages, in particular when the image is forcefully resized. With the advent of this property comes a number of new values, and browsers have their own specifications in this matter. The crisp-edges value, for example, which preserves contrast and prevents blurry edges of images, is currently translated as -webkit-optimize-contrast in Webkit browsers and nearest-neighbor in Internet Explorer.

img {
	image-rendering: crisp-edges;
	image-rendering: -webkit-optimize-contrast;/* Webkit */
	-ms-interpolation-mode: nearest-neighbor;  /* IE */
}

It’s an experimental technology, so we will likely see a few changes in the implementation.

9. Columns

The columns property allows developers to arrange web content into columns with ease. We split the content into two columns like this:

.content {
	columns: 2;
}

In the browsers that support this property – like Chrome and Safari – we will see the content arranged like so.

columns

Coupled with CSS Shape and a bit of creativity, you can have a fluid and more enticing content layout much like what you see in a fashion magazine on your websites.

10. Flex

The flex property aims to make building responsive grid more seamless while solving a couple of issues in the current mainstream method for web layout arrangement – the float property.

On top of that, by using the flex property, the web layout will take the full height of its container, which was quite cumbersome to deal with previously (take a look at our previous post on this matter: Equal Column Height With CSS).

Now, assuming you would like to build a web layout that comprises of three columns, you can have the markup arranged this way.

Column 1
Column 2
Column 3

Then, build them into columns using the flex property, like so.

#container {
	width: 600px;
	height: 300px;
	display: flex;
}
#container .col {
	flex: auto;
}

With additions of decorative styles like font and background color, we will get the following result.

flex