How do let CSS change the inset shadow on li hover, instead of resetting it?


Tags: css,menu,shadow,nav,css-selectors

Problem :

I have got a small problem with my list item on hover.

The menu bar has a small inset shadow at the bottom, defined on the li items. On li:hover the small inset at the bottom changes to a inset shadow on all 4 sides.

I`m pretty happy about how the menu reacts, except for the li:lastchild. On hover it first delete the bottom & right inset shadow and then prints the new 4 sided inset shadow. Al the other li items just change the shadow from a single bottom to all 4 sides, without resetting the shadow.

I know the css shadow part is not written very clean. But because the hover has to CHANGE te shadow instead of replace i cant simple commit a statement on multiple selectors. (If you guys know a way to do this please feel free to comment!)

So my question is, how do i get a different inset shadow on the li:lastchild which will change on hover instead of getting replaced?

The code on cedepen

        <ul class="hoofd-menu menu">
      <li class="menu-item"><a href="#">Menu Item I</a></li>
      <li class="menu-item"><a href="#">Menu Item II</a></li>
      <li class="menu-item"><a href="#">Menu Item III</a></li>
      <li class="menu-item"><a href="#">Menu Item IV</a></li>
      <li class="menu-item"><a href="#">Menu Item V</a></li>
      <li class="menu-item"><a href="#">Menu Item VI</a></li>
    </ul>


    <style> 
        .menu li {
            margin: 0 0 0 -4px;
            padding: 15px 15px;

        }

        /* Menu Item Hover effect */

        .menu li {
            box-shadow:     0 -9px 5px -5px rgba(0,0,0, 1) inset,     /* dark shadow      */
                            2px -2px 3px 0px rgba(255,255,255, 0.2),      /* white - top      */
                            2px 2px 3px 0px rgba(255,255,255, 0.2);       /* white - bottom   */
        }

        li:last-child.menu-item {
            box-shadow:     -9px 0px 5px -5px rgba(0,0,0, 1) inset,   /*dark shadow right */
                            0px -9px 5px -5px rgba(0,0,0, 1) inset,   /*dark shadow       */
                            2px -2px 3px 0px rgba(255,255,255, 0.2),      /* white - top      */
                            2px 2px 3px 0px rgba(255,255,255, 0.2);       /* white - bottom   */
        }

        li:first-child.menu-item {
            box-shadow:      0px -9px 5px -5px rgba(0,0,0, 1) inset,  /* dark shadow      */
                            -2px -2px 3px 0px rgba(255,255,255, 0.2),     /* white - left     */
                             2px -2px 3px 0px rgba(255,255,255, 0.2),     /* white - top      */
                             2px 2px 3px  0px rgba(255,255,255, 0.2);     /* white - bottom   */
        }

        .menu li:hover {
            cursor:         pointer;
            box-shadow:     -1px -1px 10px 4px rgba(0,0,0, 1) inset, /* dark shadow      */
                            2px -2px 3px 0px rgba(255,255,255, 0.2),      /* white - top      */
                            2px 2px 3px 0px rgba(255,255,255, 0.2);       /* white - bottom   */
        }

        .menu li:hover>a {
            text-shadow:    -1px -1px 3px rgba(0,0,0, 0.2);             /* text shadow      */
        }

        li:hover:last-child.menu-item {
            box-shadow:     -1px -1px 10px 4px rgba(0,0,0, 1) inset, /* dark shadow      */
                            2px -2px 3px 0px rgba(255,255,255, 0.2),      /* white - top      */
                            2px 2px 3px 0px rgba(255,255,255, 0.2);       /* white - bottom   */
        }

        li:hover:first-child.menu-item {
            box-shadow:      -1px -1px 10px 4px rgba(0,0,0, 1) inset,  /* dark shadow    */
                             -2px -2px 3px 0px rgba(255,255,255, 0.2),     /* white - top     */
                             2px -2px 3px 0px rgba(255,255,255, 0.2),      /* white - top     */
                             2px 2px 3px  0px rgba(255,255,255, 0.2);      /* white - bottom  */
        }


        /******************************************************************************************/
        /* Round corners                                                                          */
        /******************************************************************************************/
        li:first-child.menu-item {
            -moz-border-radius-bottomleft:  5px;
            border-bottom-left-radius:      5px;
            -moz-border-radius-topleft:     5px;
            border-top-left-radius:         5px;
        }

        li:last-child.menu-item {
            -moz-border-radius-bottomright: 5px;
            border-bottom-right-radius:     5px;
            -moz-border-radius-topright:    5px;
            border-top-right-radius:        5px;
        }

        /******************************************************************************************/
        /* Color palette                                                                          */
        /******************************************************************************************/

        a                       {color: #0861a5;}
        a:hover                 {color: #d98500;}
        .menu li:hover>a,
        .menu a                 {color: #dddddd;}

        body                    {background-color: #b8d3e2;}
        .menu li                {background-color: #87a0af;}

        .menu                   {font-family:       Arial, Helvetica, sans-serif}
        a                       {text-decoration:   none;}

a, .menu li>a {
    transition:         1.5s ease 0.2s;
    -moz-transition:    1.5s ease 0.2s;
    -webkit-transition: 1.5s ease 0.2s;
    -o-transition:      1.5s ease 0.2s;
}

a:hover, .menu li, .menu li:hover>a {
    transition:         0.4s ease 0.6s;
    -moz-transition:    0.4s ease 0.6s;
    -webkit-transition: 0.4s ease 0.6s;
    -o-transition:      0.4s ease 0.6s;
}

ul, li, ol {
margin: 0;
padding: 0;
border: 0;
vertical-align: baseline;
}

ul {
  margin: 100px 50px;
}

/* algemeen menu*/
.menu ul {
    list-style-type: none;
}

.menu li {
    display: inline;
}
    </style>


Solution :

If you want to make transitions with box-shadow, the elements of the box-shadow must make "pairs" and must match the "class" of the shadow. Pixels and colors can be transitioned, keywords not.

Your base element is

.menu li {
    box-shadow:     0 -9px 5px -5px rgba(0,0,0, 1) inset,   
                  2px -2px 3px 0px rgba(255,255,255, 0.2),      
                  2px 2px 3px 0px rgba(255,255,255, 0.2);   
}

and you can transition correctly to this:

   .menu li:hover {
        box-shadow:     -1px -1px 10px 4px rgba(0,0,0, 1) inset,
                        2px -2px 3px 0px rgba(255,255,255, 0.2), 
                        2px 2px 3px 0px rgba(255,255,255, 0.2);   
    }

Because the first element is inset and both cases, and the other 2 aren't in both cases.

The last child is

li:last-child.menu-item {
    box-shadow: -9px 0px 5px -5px rgba(0,0,0, 1) inset,  
                 0px -9px 5px -5px rgba(0,0,0, 1) inset,   /* PROBLEM HERE     */
                 2px -2px 3px 0px rgba(255,255,255, 0.2),     
                 2px 2px 3px 0px rgba(255,255,255, 0.2);     
    }

And the second element is inset and doesn't match the second in the hover that is not inset. THIS is the part that fails.

Once understood where the problems is there are several solutions. May be the easier is to set only 1 inset that has both x and y offsets:

li:last-child.menu-item {
    box-shadow: -9px -9px 5px -5px rgba(0,0,0, 1) inset,   /* combined shadows */
                 2px -2px 3px 0px rgba(255,255,255, 0.2),     
                 2px 2px 3px 0px rgba(255,255,255, 0.2);     
    }

The result maybe isn't exactly the previous one, but that is transitionable


    CSS Howto..

    How do I optimize a very loooong page with TONS of images on it?

    how to change the CSS background-image of a class-pseudoelement by Javascript only?

    How to add a border to only percentage of width of element, CSS Trick

    how to reference background image urls in css through config entrys

    scrollbars not showing in google chrome

    how to set a path to the static files which is surver independnet

    How to apply CSS to anchor with active class only (parent only) and not include children?

    How can I get rid of the the gap below absolutely positioned content?

    How to use Bootstrap style of BreadCrumb with my ASP.NET menu?

    How to put a background video loop on a website HTML/CSS

    How to style my HTML form using CSS

    How to redefine CSS classes with Javascript

    how to make a list float left or not according to the size of the browser?

    How can I fix an element to the page that is of a variable distance from the edge of the screen?

    How to apply format depending on absence of a CSS class?

    How to properly adjust CSS Form Select field if content is larger than image

    How to access an svg inner id and have CSS change the fill color of that id?

    How to call an HTML css style in a computed text field

    How to enlarge an image horizontally in css?

    How to position a div under a link on click?

    How to make hidden div slide down without affecting other elements in same row

    How to reverse direction of moving div once it reaches side of screen?

    How to properly serve CSS

    How to get the CSS left-property value of a div using JavaScript?

    How would you go about placing li in different divs?

    How to create class in a custom CSS file by JavaScript?

    Some doubts about how make an image clickable using CSS

    How to apply css to div content based on regex

    How to put text over img on hover - width and height are variable

    How do I confer CSS properties upon elements retrieved from $.ajax()?