Passion & Opportunity ? continue : break

How to use CSS attr() function?
Written: 2019-01-14 22:21:26 Last update: 2019-04-19 09:22:35

As of 20190124, CSS attr() function to generate content for pseudo-elements is supported on most browsers including IE8, but CSS3 attr() function to get all other properties is still not final and no browser support yet.

There are many use cases to utilize attr() and 'data-*', but in my experience mostly are:

  • When there are many repeations (eg: $ currency symbol), using pesudo element can reduce size.
  • To avoid typing-error when dealing with many repeation.
  • To create simple tooltip

Below is the demo to create tooltip using pseudo element and attr(), the default browser tooltip using 'title' attribute is too slow and ugly (cannot be styled), tooltip is very important and there are many sites using tooltip from simple text tooltip to full graphic tooltip with image and link such as Wikipedia site.

Please use mouse to hover the items to see the styled tooltip.


Armadillo Barracuda Chameleon Dragonfly Eagle Fox Giraffe Horse Armadillo Barracuda Chameleon Dragonfly Eagle Fox Giraffe Horse Armadillo Barracuda Chameleon Dragonfly Eagle Fox Giraffe Horse

To create the above example, we only need the following style:

.tooltip {
  flex: 1 1 auto; /* optional, for flex demo */

  text-decoration: none;
  padding: 5px 10px;

  color: #ccc;
  border: 1px solid #666;

  /* IMPORTANT, set relative, so children able to use position: absolute */
  position: relative;

  text-align: center;
}
.tooltip:hover {
  color: #fff;
  background-color: #666;
  /* cursor: pointer; */
}
.tooltip::before {
  /* create pseudo element for tooltip message */
  content: attr(data-tooltip);

  cursor: default;

  white-space: nowrap;

  /* position is absolute to the 'relative' parent, centered below parent */
  position: absolute;
  top: 125%; /* 1 line below parent */

  /* default CENTER-ALIGNED */
  left: 50%; /* in the middle (right) */
  transform: translateX(-50%); /* move to the left */

  /* default hidden, will be shown on hover */
  visibility: hidden;
  /*display: none; */ /* do not use display: none because transition will not work, just use visibility */
  opacity: 0.0; /* for animation (transition) */

  transition: opacity 1.0s ease; /* animation */

  z-index: 9; /* make it on-top of other content */

  /* tooltip box style */
  font-size: 1.0em;
  padding: 5px 10px;

  color: #0f0;
  background-color: #022;
  border: 2px solid #0f0;
  border-radius: 5px;
}
.tooltip:hover:before {
  /* display tooltip */
  visibility: visible;
  /*display: inline-block; */
  opacity: 1.0; /* for animation (transition) */
}
.tooltip.aleft:before {
  /* LEFT-ALIGNED */
  left: 0;
  right: auto;
  transform: none;
}
.tooltip.aright:before {
  /* RIGHT-ALIGNED */
  left: auto;
  right: 0;
  transform: none;
}
The item's tooltip text will be stored using attribute 'data-tooltip', for example:
<a class="tooltip" data-tooltip="is a tall and long-necked mammal">Giraffe</a>

It is simple and sweet if the tooltip text is short but if it too long then maybe the tooltip will go outside left/right screen, because using pure CSS so we can not re-position the pseudo element to be always inside the screen, we can add CSS class to set 'left' and 'right' position but need Javascript if we want to manipulate the exact position.

Another useful usecase which I found is to reduce content for my own blog site, maybe we use many tag <a> links, so using attr() may shorten the content, eg:

<a href="https://css-tricks.com/css-attr-function-got-nothin-custom-properties/"></a>
Without using CSS attr() the above statement will not display anything because there is no content inside <a> tag but if we add following style with :empty selector:
a[href]:empty::after {
  content: attr(href);
}
This style mean to select all 'a' tags which has 'href' attribute and the content is 'empty', this CSS will create pseudo content from the href value, the result will be:

I am wishing the spec for CSS attr() to capture all attributes values (eg: attr(width), attr(display), etc.) can be finalized and implemented by modern browsers, if this feature is done then the front-end developer will have much more useful ideas and will use less Javascript code for simple UI layout, in the mean time please keep checking the CSS attr() spec for further update.

HTML and CSS should be enough for managing content and layout, using Javascript for just simple layout because CSS spec is not exist, or not final or browser support is inadequate is simply irritating .. what do you think?