Search code examples
htmlcsspseudo-elementpseudo-classbox-shadow

How to apply transform effect to box-shadow only


I'm building a menu that uses the :hover pseudo classes to display a box-shadow.

Here's a nav item as normal and here's the same item under :hover.

I'm using the transform property to apply a skew to the box-shadow, so that it looks like a chunky, overlapping, slanted underline.

.link:hover {
    box-shadow: 0 -0.5em 0 #7ed6df inset;
    transform: skew(-20deg);
}

As you can see, the skew works, but it also skews the .link text when I only want the box-shadow to be skewed.

I tried to create a parent style with @apply like so:

--link-underline: {
    box-shadow: 0 -0.5em 0 #7ed6df inset;
    transform: skew(-20deg);
}

...

.link:hover {
    @apply --link-underline;
}

but there was no change when I hovered over the link, and I toyed with an ::after pseudo element that added the shadow to an invisible text element, but couldn't find a fix that worked there either. I would be so grateful for any advice. Thank you!


Solution

  • After fiddling with pseudo elements and classes more, I have a working solution!

    First I added these two properties to my original .link class, making sure the text was stabilised:

    display: inline;
    position: relative;
    

    Then I created an ::after pseudo element for my .link class:

    .link::after {
        content: '';
        position: absolute;
        z-index: -1;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        box-shadow: 0 -0.5em 0 #7ed6df inset;
        transform: skew(-20deg);
        opacity: 0;
    }
    

    This element uses the z-index to sit underneath the original text, and hides itself with 0 opacity. The box shadow and the skew are applied to this ::after element, but because its content is empty, no text is affected. All I needed to do then was add the :hover function, which puts the pseudo class onto 1 opacity:

    .link:hover::after {
        opacity: 1;
    }
    

    Thank you for the suggestions, I wanted to use box-shadow for this as I am trying to animate a swiping motion too.