CSS doesnāt get much love these days. Hating CSS has become so popular, that every couple of weeks one of my developer buddies posts the same meme on Twitter. As someone who enjoys CSS, and almost exclusively writes plain olā CSS, Iāll give my hot take on that topic in a future post. For now, I'll share a few underutilized CSS features that can make your dev experience more pleasant and hopefully help you enjoy the misunderstood language. To make this more fun, Iām going to use all 4 in the same example.Ā
:not()
A pseudo-class that allows you to exclude a specific element or elements from being selected. This is an interesting one because you can do some complex stuff. Hilariously, with a little bit of imagination, you can turn this thing into a visual linting tool.
Take this list for example;
<ul class="list">
<li class="listItem">List item</li>
<li class="listItem">List item</li>
<li class="listItem">List item</li>
<li class="listItem">List item</li>
</ul>
![copy](/clipBoardIcon.png)
.list{
list-style-type:none;
padding: 32px;
border:solid 2px;
border-radius:5px;
}
.listItem{
padding:8px 0;
margin: 4px 0;
}
![copy](/clipBoardIcon.png)
A simple list containing four elements. We want to be able to add bottom borders to all the items except the last one. We can do this by using :not()
with :last-child.
.listItem:not(:last-child) {
border-bottom: solid 1px;
font-size:1.3rem;
font-style: italic;
}
![copy](/clipBoardIcon.png)
You can also negate multiple elements at the same time; Ā :not(.first, div)
or :not(.first):not(div)
Letās also exclude the Subscribe call to action
<li class="listItem">Subscribe</li>
![copy](/clipBoardIcon.png)
.listItem:not(:last-child, #sub)
![copy](/clipBoardIcon.png)
This thing lints!
You can use :not()Ā
to check for missing attributes in your HTML by pairing it with an attribute selector. For example, in my menu component, I added <a>
tags inside my list items and I wanted to make sure that they all had title attributes. Well, I could simply add properties to every <a>
tag that doesnāt have the attribute! I even threw in a little text with the pseudo-element ::after
.
a:not([title]) {
outline: dotted 2px red;
}
a:not([title]):after {
content: "add title!";
}
![copy](/clipBoardIcon.png)
Use this on your outbound links to spotĀ .outbound:not([rel=ānoopenerā])Ā
or missing alts in your images img:not([alt])
. Good stuff!
::first-letter
This is an intuitive pseudo-element that simply allows you to select the first letter of an element. Use this to style your text without making a mess of your HTML. e.g make your WordPress blog entries look like a page from the Gutenberg bible.
Letās use this to pimp out our menu. Letās also pair it with :not()
to exclude the first letters of the items we donāt want to style.
.listItem:not(:last-child, #sub)::first-letter {
color: red;
font-size: 1.6rem;
font-weight: 600;
}
![copy](/clipBoardIcon.png)
clip-path
This property lets you clip an element to either a basic shapeĀ clip-path: circle(50%);
or something more complex.
I added an avatar image element above:
<li class="listItem frame" id="avatar">
Ā Ā Ā Ā <div class="avatarInner frame"></div>
</li>
![copy](/clipBoardIcon.png)
#avatar {
height: 80px;
width: 80px;
background: #000;
display: flex;
justify-content: center;
align-items: center;
background-image: linear-gradient(to bottom left, #ff0000, #000);
margin-bottom: 12px;
}
.avatarInner {
height: calc(100% - 8px);
width: calc(100% - 8px);
background: url(https://url.url);
background-size: cover;
background-repeat: no-repeat;
}
.frame {
clip-path: polygon(
13% 0,
100% 0,
100% 30%,
100% 70%,
100% 100%,
0 100%,
0% 70%,
0 13%
);
}
![copy](/clipBoardIcon.png)
Now, donāt worry, you donāt have to come up with a shape using percentages. I use this generator to create the values. There are also other more advanced tools out there that pretty much let you draw with clip-path.Ā
This property is very useful in making @keyframes animations. In fact, the image component animation on my blog feed and pages uses it to create the glitch effect.Ā Ā
backdrop-filter
This CSS property allows you to add graphical effects behind an element. It takes in the same functions as the filter property and you can apply multiple effects to one element.
backdrop-filter: url(filters.svg#filter) blur(4px) saturate(150%);
![copy](/clipBoardIcon.png)
For this example, I created a hover event to display a call to action over my avatar image. I used blur()
on a transparent red background.
.hover {
backdrop-filter: blur(3px);
background: rgb(255, 30, 0, 0.5);
box-sizing: border-box;
width: 65px;
height: 65px;
margin: auto;
color: #fff;
display: none;
align-items: center;
position: absolute;
z-index: 4;
text-align: center;
padding: 4px;
justify-content: center;
}
#avatar:hover > .hover {
display: flex;
}
![copy](/clipBoardIcon.png)
In addition to producing stunning frosted glass effects, the main benefit of this design technique is being able to have background images or complex background elements while keeping your text readable.
Letās turn our little list into a proper menu sidebar to demonstrate this;
.menu {
list-style-type: none;
padding: 32px;
border: solid 1px gray;
display: flex;
flex-direction: column;
backdrop-filter: grayscale(50%) blur(6px);
height: 100vh;
width: 120px;
}
![copy](/clipBoardIcon.png)
I added a vivid background image then used backdrop-filter:
with grayscale()
and blur()
to create the frosted glass look on my .menu
bar.Ā
Check it out on Codepen
:not()
read more
:first-letter
read moreĀ
clip-path
read moreĀ
Backdrop-filter
read moreĀ
Ā