2020-04-18
|~3 min read
|512 words
The navigation of Sick Fits, the fake storefront from Wes Bos’s Advanced React Course, is pretty … sick.
Specifically, I liked two things:
To understand both better, I pull together a CodePen to explore the ideas further.
(Note: The embedded version appears to have some significant lag / styling problems. For the best experience, look at it on CodePen itself.)
For a relatively simple demo, there’s was quite a bit of CSS involved (at least for me).
The key CSS for adding the animation is:
li:after {
height: 2px;
content: "";
background: red;
width: 0;
position: absolute;
transform: translateX(-50%);
transition: width 0.7s;
transition-timing-function: cubic-bezier(1, 0.65, 0, 2.31);
left: 50%;
margin-top: 1.25rem;
}
li:hover:after,
li:focus:after {
width: calc(100% - 70px);
}
What’s going on / some lessons learned:
:after
creates a pseudo-element that will be the “last child” of the selected element - in this case, each of the li
s.li
and not appended to it’s right like a normal flow, I use position: absolute
content:''
is important.height: 2px
li
tags (that’s the :after
’s function). But, we start with no content - though setting it to empty is necessary.:hover:after
and :focus:after
that the width is reset from 0 to a new dynamically calculated range. This was another gotcha as the CSS calc function is rather particular, i.e. the spaces are not optional.Handling the skewed outline was similarly achieved, though instead of :after
, I used a :before
.
li:before {
content: "";
width: 2px;
background: grey;
height: 100%;
left: 0;
position: absolute;
transform: skew(-20deg);
top: 0;
bottom: 0;
}
li:first-child:before {
background: transparent;
}
The one part slightly new piece here is using the :first-child:before
to remove the divider on the very first li
. I did this as it wasn’t going to appear on the last one anyway.
Also worth noting: because I’m using both :before
and :after
, I could just put the same style in the :last-child:after
- since that would override the other :after
I set or be overridden by it. Hooray for the cascading part of CSS.
This was a fun detour to learn some new CSS tricks and I’m particularly pleased in how performant it is - particularly relative to some of the other approaches I found for animating borders.
Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!