Search code examples
htmlcssbox-shadow

How can I create a shadow behind a border?


I have a anchor containing a span element containing my text. The span element has these attributes

border-bottom: 5px solid #59DFB8;
padding-bottom: 2px;

Now I want to create a shadow behind the border, but not the whole text. How would I do that without giving up on responsiveness?

.selected {
    border-bottom: 5px solid #59DFB8;
    padding-bottom: 2px;
    box-shadow: 10px 10px 10px #59DFB8;
}
<div class="nav">
    <ul>
        <li><a href="index.html"><span class="selected">Home</span><span class="shadow"></span></a></li>
        <li><a href="">Projects</a></li>
        <li><a href="about.html">About</a></li>
      </ul>
</div>

Example: Example of the effect I want


Solution

  • The box-shadow property always uses its containing element's bounding box. You can't apply it to just part of an element, so you'll need to create an element specifically for the part that you want to have a shadow.

    One solution would be to use pseudo-elements to create a child of the .selected element, and make that child look like an underline / bottom border. Then you can apply box-shadow to that.

    Make your .selected element inline-block, so that its width is sized to its content. Then use the ::after pseudo-selector to create a block element inside of that, sized to the parent's width with a height of 5px and a solid background.

    .selected {
        /* so that its bounding box is only as wide as its contents */
        display: inline-block;
    }
    
    .selected::after {
        /* pseudo-elements must have content in order to render; give it a blank string */
        content: '';
        /* so it fills the parent horizontally */
        display: block;
        /* adjust to how tall you want the "bottom border" to be */
        height: 5px;
        /* color for the "bottom border" */
        background: #59DFB8;
        /* here's the shadow effect, adjust offsets and color as desired */
        box-shadow: 10px 10px 10px #59DFB8;
    }
    

    Here is a full example, with simplified markup and some extra styles to make it look more like your example image.

    ul {
        list-style: none;
        display: block;
        background: #003447;
        padding: 20px;
    }
    
    ul li {
        display: inline-block;
        padding-left: 20px;
        padding-right: 20px;
    }
    
    ul li a {
        font-family: Arial, sans-serif;
        font-size: 20px;
        color: #59DFB8;
        text-decoration: none;
        text-transform: uppercase;
    }
    
    ul li a::after {
        content: '';
        display: block;
        margin-top: 5px;
        height: 2px;
        background: #59DFB8;
    }
    
    ul li a.selected::after {
        box-shadow: 0px 0px 10px 1px #59DFB8;
    }
    
    ul li a:active::after,
    ul li a:hover::after {
        visibility: hidden;
    }
    
    
    ul li a.selected:active::after,
    ul li a.selected:hover::after {
        visibility: visible;
    }
    <ul>
        <li><a href="index.html" class="selected">Home</a></li>
        <li><a href="">Projects</a></li>
        <li><a href="about.html">About</a></li>
    </ul>