css if and attr

css if and attr

csswebdev

CSS is growing! When I started my career CSS was a simple "language" and everyone hated it because of it's perks and lack of functionalities, or specific behavior in many cases. Nowadays it became more advanced, it has variables, built-in styles nesting, ability to communicate with HTML (attr) and now even some logic, like if! It is pretty impressive how it has changed over the years, but often the more options you have, the more lost you feel - what shuld you choose? What is the best option, or real-life use? Today we will go through attr and if features to see how we can use it!

attr

attr stands for attribute, and at the beginning it was mostly used for "content" property in pseudo elements like :before or :after :

.element {
  position: relative;

  &:after {
    position: absolute;
    content: attr(data-username);
    display: inline-block;
    top: 0;
    left: 0;
  }
}

and sadly it could not be used for other properties, like for example this

.element {
  color: attr(data-color);
}

but nowadays it is possible! Sadly, support is still not that great (tfu, Chrome monopoly!), but I hope it will improve soon. Nevertheless, when I was writing a simple grid for this blog purposes, I thought about how good it would be to be able to use attr with grid-area, and here we go!

Let's assume that we have this structure in html:

<div class="grid">
	<div area="header"></div>
	<div area="side"></div>
	<div area="content"></div>
</div>

and in css, using grid and named areas, we can define structure of the grid, and link particular elements to it directly from HTML!

.grid {
  width: min(100%, 600px);
  display: grid;
  grid-template-columns: 1fr 100px;
  grid-template-areas: 
    "header header" 
    "breadcrumbs side" 
    "content side" 
    "footer footer";
  grid-template-rows: 50px 30px 1fr 50px;
  gap: 1rem;
		
  & > * {
    grid-area: attr(area type(<custom-ident>)); /* read the data attribute to get the grid-area name - CHROME ONLY AT THIS POINT */
  }
}

Demo https://codepen.io/cbolson/pen/raVXxmb

Grid tip:

I often find people struggle with responsive grid and do some weird stuff to rearrange alignment of elements, remember that you can do this:

.grid {
  grid-template-areas: 
    "header header" 
    "breadcrumbs side" 
    "content side" 
    "footer footer";
		
  @media all and (max-width: 732px) {
    grid-template-areas: 
      "header header" 
      "breadcrumbs breadcrumbs" 
      "content content" 
      "footer footer";
  }
}

so basically, you just change the grid structure in root element, instead of changing, for example, as many people do, child elements areas.

if

And if! Oh lord, when we will get for and CSS will turn into real language it will be mess... fun! I meant fun! :D Nevertheless, logic constructions like if's allows us to create styles in completely different way, now, instead of using specific classes or JS, we can just write this logic directly, inside of the styles! And let's see how it can work with attr:

<div class="card" data-status="pending">something</div>
.card {
  --status: attr(data-status type(<custom-ident>));
	border-color: if(
	  style(--status: pending): royalblue;
	  style(--status: complete): seagreen;
	  else: gray);
	background-color: if(
	  style(--status: pending): #eff7fa;
		style(--status: complete): #f6fff6;
		else: #f7f7f7);
}

Demo: https://codepen.io/una/pen/vEOEzPa

Although, I'm not sure if the above example is the best to show you all the possibilities, because you could accomplish the same with basic queries:

.card {
  /* ... */
	
	&[data-status="pending"] {
	  border-color: royalblue;
	}
}

but I hope you get the idea - CSS is more flexible and do not be afraid of using it and exploring your own ways. Have fun!