Search code examples
cssz-indextransitionshorthandbox-shadow

CSS transition for element A by hover element B


I have a vertical sidebar with buttons on it.

By hovering a button, the button should ease out to right (for title text).

I did that via "transition: with"

   nav#navi_side a {
   display:block;
   width:30px;
   height:30px;
   background:linear-gradient(100deg, rgb(250,250,250) 0%, rgb(225,225,225) 30%, rgb(200,200,200) 70%, rgb(175,175,175) 100%);
   border-radius:5px;
   box-shadow:1px 1px 1px rgba(250,250,250,0.75), -1px -1px 1px rgba(25,25,25,0.50);
   text-align:left;
   line-height:30px;
   transition:width 1s ease-in-out;
}
nav#navi_side a:hover {
    width:150px;
    background:linear-gradient(100deg, rgb(250,250,250) 0%, rgb(225,225,225) 30%, rgb(200,200,200) 70%, rgb(175,175,175) 100%);
    transition:width 0.25s ease-in-out;
}
   <nav id="navi_side">
    <ul>
     <li class="one"><a href="">A</a></li>
     <li class="two"><a href="">B</a></li>
     <li><a href="">C</a></li>
     <li><a href="">D</a></li>
     <li><a href="">E</a></li>
    </ul>
    <ul>
     <li><a href="">F</a></li>
     <li><a href="">G</a></li>
     <li><a href="">H</a></li>
    </ul>
    <ul>
     <li><a href="">I</a></li>
     <li><a href="">J</a></li>
     <li><a href="">K</a></li>
     <li><a href="">L</a></li>
    </ul>
</nav>

But it's all on a grey bar (maybe the <UL>).

How can I get a shadow (box-shadow) in transition but only downside the bar (<UL>) and not on it.


Solution

  • The desired effect is achieved with the help of the :before and :after selectors. The :before selector is used to cover up the remainder of the bottom box-shadow, while the :after selector is used to manipulate its width, which is expressed in % for transition purposes. The transition effect is applied to the width, background-color and box-shadow with the transition-property set to all:

    #navi_side {
      /*float:left;*/
      position:fixed;
      /*display:block;*/
      margin-left:7px;
    }
    
    #navi_side ul {
      width:40px;
      padding:0.1px 0;
      background-color:#FF6600; /* modified */
      border-radius:5px;
    }
    
    #navi_side ul:not(:last-of-type) {
      margin-bottom:10px;
    }
    
    #navi_side li {
      position:relative; /* added */
      width:30px;
      height:30px;
      margin:5px;
      border-radius:5px;
      transition:all 1s ease-in-out; /* modified */
      list-style-type:none;
      background-color:#00CCFF; /* added */
      cursor:pointer; /* addition */
    }
    
    #navi_side li:hover {
      width:200px; /* modified */
      box-shadow:5px 6px 2.5px -2.5px Gray; /* adjust to your needs / has to be set here in order to enable its transition with the :after selector */
      transition:all 0.25s ease-in-out; /* modified */
      background-color:#99FF33; /* added */
    }
    
    /* added */
    
    #navi_side li:before {
      content:"";
      position:absolute;
      top:0;
      left:0;
      width:35px; /* the remainder of 200px + 5px right margin */
      height:inherit;
      box-shadow:0 6px 2.5px -2.5px #FF6600; /* to cover up the remainder of the bottom box-shadow */
    }
    
    #navi_side li:hover:after {
      content:"";
      position:absolute;
      top:0;
      right:0;
      width:85%; /* adjusting the width of the box-shadow / 85% is the same as 170px, needs to be in % not px */
      height:inherit; /* ideally */
      box-shadow:inherit; /* the box-shadow has to be inherited in order to enable its transition with the :after selector */
      border-radius:5px;
      z-index:-1;
    }
    
    /* not necessary, at least not with this example
    #navi_side li:hover a {
      display:block;
      width:100%;
      height:30px;
      background:green;
      border-radius:5px;
    }
    
    #navi_side li:hover div {
      position:relative;
      z-index:-1;
      display:block;
      width:100%;
      height:30px;
      margin-top:-30px;
      background:red;
      border-radius:5px;
      box-shadow:5px 5px 10px black;
    }
    */
    <nav id="navi_side">
      <ul>
        <li><a href="">F</a></li>
        <li><a href="">G</a></li>
        <li><a href="">F</a></li>
        <li><a href="">G</a></li>
        <li><a href="">H</a></li>
      </ul>
      <ul>
        <li><a href="">F</a></li>
        <li><a href="">G</a></li>
        <li><a href="">H</a></li>
      </ul>
      <ul>
        <li><a href="">I</a></li>
        <li><a href="">J</a></li>
        <li><a href="">K</a></li>
        <li><a href="">L</a></li>
      </ul>
    </nav>

    Note: The transition effects with the :before and :after selectors can be achieved if the values of the properties you want to apply the transition to, are inherited form their parent elements.