Fancy Menu Hover Effects
Codrops is a great source of info. One of their articles is about creating cool hover effects for menus. The effects are cool but I’ve never found them easy to implement. And because of that difficulty they’re time consuming to implement so easy to not to bother with. This article is an attempt to get a better understanding of how these work.
Menu example
Here’s an example of one menu.
How?
There are a number of important principles that underscore these effects. They use some or all of the following:
- The
:hover
pseudo-selector obviously (so not much use for mobile) - The pseudo-elements
::before
and::after
and styling these into shapes and lines or even other words. - Because
::before
and::after
use the defaultdisplay: inline;
you need to change thisdisplay: inline-block
orposition: absolute
so thattransform
and other CSS properties will work on them. You can also usegrid
orflex
and they will behave as child elements (that can presumabley be re-ordered!). - A
transition
property because animations happen over time, even if it’s only two tenths of a second. - A transform property. These allow movement of an element that won’t affect nearby objects. If using more than one keep them together:
transform: scale(0.7) opacity: 0.1 translateX(150%);
- Changing the
position
value toabsolute
orrelative
- Using
opacity
to fade effects in and out. - Using the
z-index
to stack the pseudo-elements. The parent can be set toisolation: isolate
to keep the stacking context within itself, thus prevent the pseudo elements ending up behind it.
Optionally some effects may use:
- a data attribute on the anchor tag:
<a href="#" data-hover="menu 1">
that can be used in the::before
or::after
content value:content: attr(data-hover);
- Some
<span>
tags inside the anchor tags. - The property
pointer-events
has a default ofauto
but might need to be set tonone
, particularly on pseudo-elements to stop them reacting to the cursor. This switches off things likecursor: pointer
on links. backface-visibility
is used when a 3D rotation takes place. The default value isvisible
meaning you’ll see text from the other side. You can set it tobackface-visibility: hidden
if you want to hide it.
Some things to watch out for
-
You often want to style
::before
and::after
together. But you cannot use these pseudo elements with:is()
and:where()
. -
When you hover you are hovering over the anchor element NOT it’s pseudo elements which may not even be visible. Therefore watch your syntax: use
a:hover::before
and NOTa::before:hover
. -
Using
z-index
on pseudo elements is tricky.Firstly if the parent’s display is neither to
grid
norflex
it won’t work unless theposition
value is set to something other than the default ofstatic
, egrelative
.Secondly using
postion: relative
with az-index
value creates a new stacking context. This means all z-index values are relative to this particular group or parent and child elements.Thirdly because although the pseudo-elements are inside their parent element they can end up behind out out of view. You may want something behind the text but still visible. So
a::before
is insidea
. To make this work set the pseudo-element (inside) to a negative value and the parent to a positive one. Setting parent’sz-index
from the default ofauto
sets a new stacking context for it’s chidren. Now they can’t go behind the parent.A better way is is to set
isolation: isolate
on the parent instead of az-index
value. This means the parent’s layering position is not fixed. It is also more obvious what the intention is when we read the code. -
When setting the
position: absolute
in the pseudo-elements don’t forget to setposition: relative
in the parent, ie. in these cases the anchor tag.
Z-index rules
So after writing the above I thought I’d better write a brief synopsis of rules around the z-index.
- Only works on elements that have a position set (ie. not the default of
static
). - When a stacking context is set the root element is at the back, then elements with a negative z-index, then elements with no z-index (default is 0?), then elements with a positive z-index.
- If two or more elements have the same z-index (or is unset) the order is determined by their position in the HTML document. Lower down in the doc appear above those lower down.