8 Clever Tricks with CSS Functions

By Anselm Urban

CSS is capable of much more than many web developers realise. The stylesheet language continues to get more and more powerful with every passing year, bringing functionality to the browser that otherwise would be fulfilled by JavaScript. In this article, we’ll take a look at eight clever tricks with CSS functions that do not require JavaScript at all.

1. Pure CSS Tooltips

A lot of websites still use JavaScript to create tooltips but it is actually much easier with CSS. The simplest solution is to provide the tooltip text in a data attribute in your HTML code, e.g. data-tooltip="…". With that in your markup, you can then place the following into your CSS to display the tooltip text inside the attr() function:

.tooltip::after {
  content: attr(data-tooltip);

Quite self-explanatory, right? Of course, there is more code needed to actually style the tooltips but fear not, there is an awesome, pure CSS library for this exact purpose called Hint.css.

2. (Ab)using Custom Data Attributes and the attr() Function

We already used attr() for tooltips but there are some other use cases for it too. In combination with data attributes, you can build a thumbnail image with title and description using just one single line of HTML code:

<a class="caption" href="#" data-title="Vulture" data-description="...">
  <img src="img.jpg" alt="Illustration"/>

Now you can use the attr() function to display the title and description:

.caption::after {
  content: attr(data-title);

Here’s a working example of a thumbnail with animated captions that show on hover:

See the Pen Thumbnail with Animated Captions by SitePoint (@SitePoint) on CodePen.

Note: Generated content could be problematic in terms of accessibility. This article on accessibility support for CSS generated content is a useful read on that very topic.

3. CSS Counters

What you can do with CSS counters seems like magic. It is not the most well-known feature and most people probably would guess that it is not so well supported but actually, every browser supports CSS counters:

See Can I Use css-counters? Data on support for the css-counters feature across the major browsers from

While you should not use CSS counters for ordered lists (<ol>), counters are great for things like pagination or displaying numbers underneath items in a gallery. You can also count the number of checked items which is quite impressing given how little code you need (and no JavaScript):

See the Pen Selection CSS Counter by Will Boyd (@lonekorean) on CodePen.

CSS counters are also great for dynamically changing numbers in a list of items which can be reordered by dragging and dropping:

See the Pen CSS Counters drag-and-drop demonstration by SitePoint (@SitePoint) on CodePen.

Just as with the last example, remember — generated content could be problematic in terms of accessibility.

4. Frosted Glass with CSS Filters

With iOS 7, Apple brought us the “frosted glass” effect — translucent, blurry elements that look like a frosted glass window. This effect is starting to appear in many of places, inspired by Apple’s implementation. Recreating this effect is a bit tricky — before there were CSS filters, you had to create the frosted glass effect with blurred images. Now that CSS filters are fully supported by almost all major browsers, it is much easier to recreate this effect.

See Can I Use css-filters? Data on support for the css-filters feature across the major browsers from

In the future, we could create similar effects using backdrop filters and the filter() function which are both currently only supported by Safari.

5. Using HTML Elements as Background Images

Normally, you would specify a JPEG or PNG file as background image or maybe a gradient. But did you know that with the element() function, you can also use a <div> as a background image? Currently, the element() function is only supported by Firefox:

See Can I Use css-element-function? Data on support for the css-element-function feature across the major browsers from

The possibilities are nearly endless, here is one example from MDN.

6. Smarter Grids with calc()

Fluid grids are a great thing but there are some serious problems. For instance, it is impossible to have a gutter on the top and bottom that is the same size as a gutter on the left and right. Also, the markup is really messed up, depending on which grid system you use. Even flexbox alone is not the ultimate solution but with the calc() function which can be used as a value in CSS, grids can become much better. In this tutorial here at SitePoint, George Martsoukos shows some practical examples, such as a gallery grid with perfect spacing. Using CSS preprocessors such as Sass, putting together a creative grid system can be incredibly simple and easy to maintain. With browser support also being nearly perfect, calc() is a handy feature you should definitely use.

See Can I Use calc? Data on support for the calc feature across the major browsers from

7. Aligning position:fixed Elements with CSS calc()

Another use case for the calc() function is aligning elements with a fixed position. For example, if you have a content wrapper with fluid spacing to the left and right, and you want to precisely align a fixed element inside of that wrapper — you’re going to have a hard time figuring out which value to choose for the “right” or “left” property. With calc(), you can combine relative and absolute values to perfectly align the element:

.wrapper {
  max-width: 1060px;
  margin: 0 auto;
.floating-bubble {
  position: fixed;
  right: calc(50% - 530px); /* 50% - half your wrapper width */

Here’s an example:

See the Pen Aligning “position: fixed” elements with CSS calc() by SitePoint (@SitePoint) on CodePen.

8. Animations with cubic-bezier()

To make the UI of a website or app more attractive, you can use animations but the standard easing options are pretty limited. For example, "linear" or "ease-in-out". Things like bouncy animations aren’t even possible with the standard options. With the cubic-bezier() function, you can animate elements exactly the way you want.

There are two ways to use cubic-bezier() — understanding the mathematics behind it and building it yourself, or using a cubic-bezier generator.

Honestly, I’d go with the latter.


A clever use of CSS functions not only solves known problems like establishing smarter grid systems but it also gives you more creative freedom. With browser support getting better and better, you should really take a critical look at your CSS and improve it with functions like calc().

  • Marc R.

    Some nice and interesting things you mentioned there ;) But i experience some Problems with tablet, depending on view. Great Article. Keep up the good work!

  • zzzzbov

    My understanding is that generated content isn’t read by screen readers, so be sure to provide an accessible alternative if you go that route.

    • It depends on the screen reader but it is always a good idea to provide fallback content, not only for generated content but also images, icons etc.

  • Nice work. I love playing with these edgy CSS features and seeing what they can do.

  • Marc R.

    It would be really helpful if you comment your code a little bit. For me as a newbie its really hard to follow. But still very interesting ! :)

  • Wahyudies

    Awesome trick, and i was realized modern css can do math.

  • ANZ

    As for the apple frost effect, in a while you can use css’ backdrop-filter. Supported by Safari and currently with experimental support in Chrome.

  • mselmany

    .tooltip::after {
    content: attr(data-tooltip);

    this is usable than above :

    [data-tooltip]::after {
    content: attr(data-tooltip);

  • M S i N Lund

    LOL @ element()

    “This page best viewed with Firefox 4, or better”

    …do we dare?


  • Kathryn Crawford

    Any examples of what ways we could use HTML elements as background images? I really can’t think of a practical way to use it.

Get the latest in Front-end, once a week, for free.