[css] CSS 3 slide-in from left transition

Is there a cross browser solution to produce a slide-in transition with CSS only, no javascript? Below is an example of the html content:

<div>
    <img id="slide" src="http://.../img.jpg />
</div>

This question is related to css css-transitions

The answer is


Use CSS3 2D transform to avoid performance issues (mobile)

A common pitfall is to animate left/top/right/bottom properties instead of using to achieve the same effect. For a variety of reasons, the semantics of transforms make them easier to offload, but left/top/right/bottom are much more difficult.

Source: Mozilla Developer Network (MDN)


Demo:

_x000D_
_x000D_
var $slider = document.getElementById('slider');
var $toggle = document.getElementById('toggle');

$toggle.addEventListener('click', function() {
    var isOpen = $slider.classList.contains('slide-in');

    $slider.setAttribute('class', isOpen ? 'slide-out' : 'slide-in');
});
_x000D_
#slider {
    position: absolute;
    width: 100px;
    height: 100px;
    background: blue;
    transform: translateX(-100%);
    -webkit-transform: translateX(-100%);
}

.slide-in {
    animation: slide-in 0.5s forwards;
    -webkit-animation: slide-in 0.5s forwards;
}

.slide-out {
    animation: slide-out 0.5s forwards;
    -webkit-animation: slide-out 0.5s forwards;
}
    
@keyframes slide-in {
    100% { transform: translateX(0%); }
}

@-webkit-keyframes slide-in {
    100% { -webkit-transform: translateX(0%); }
}
    
@keyframes slide-out {
    0% { transform: translateX(0%); }
    100% { transform: translateX(-100%); }
}

@-webkit-keyframes slide-out {
    0% { -webkit-transform: translateX(0%); }
    100% { -webkit-transform: translateX(-100%); }
}
_x000D_
<div id="slider" class="slide-in">
    <ul>
        <li>Lorem</li>
        <li>Ipsum</li>
        <li>Dolor</li>
    </ul>
</div>

<button id="toggle" style="position:absolute; top: 120px;">Toggle</button>
_x000D_
_x000D_
_x000D_


Here is another solution using css transform (for performance purposes on mobiles, see answer of @mate64 ) without having to use animations and keyframes.

I created two versions to slide-in from either side.

_x000D_
_x000D_
$('#toggle').click(function() {_x000D_
  $('.slide-in').toggleClass('show');_x000D_
});
_x000D_
.slide-in {_x000D_
  z-index: 10; /* to position it in front of the other content */_x000D_
  position: absolute;_x000D_
  overflow: hidden; /* to prevent scrollbar appearing */_x000D_
}_x000D_
_x000D_
.slide-in.from-left {_x000D_
  left: 0;_x000D_
}_x000D_
_x000D_
.slide-in.from-right {_x000D_
  right: 0;_x000D_
}_x000D_
_x000D_
.slide-in-content {_x000D_
  padding: 5px 20px;_x000D_
  background: #eee;_x000D_
  transition: transform .5s ease; /* our nice transition */_x000D_
}_x000D_
_x000D_
.slide-in.from-left .slide-in-content {_x000D_
  transform: translateX(-100%);_x000D_
  -webkit-transform: translateX(-100%);_x000D_
}_x000D_
_x000D_
.slide-in.from-right .slide-in-content {_x000D_
  transform: translateX(100%);_x000D_
  -webkit-transform: translateX(100%);_x000D_
}_x000D_
_x000D_
.slide-in.show .slide-in-content {_x000D_
  transform: translateX(0);_x000D_
  -webkit-transform: translateX(0);_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div class="slide-in from-left">_x000D_
  <div class="slide-in-content">_x000D_
    <ul>_x000D_
      <li>Lorem</li>_x000D_
      <li>Ipsum</li>_x000D_
      <li>Dolor</li>_x000D_
    </ul>_x000D_
  </div>_x000D_
</div>_x000D_
_x000D_
<div class="slide-in from-right">_x000D_
  <div class="slide-in-content">_x000D_
    <ul>_x000D_
      <li>One</li>_x000D_
      <li>Two</li>_x000D_
      <li>Three</li>_x000D_
    </ul>_x000D_
  </div>_x000D_
</div>_x000D_
_x000D_
<button id="toggle" style="position:absolute; top: 120px;">Toggle</button>
_x000D_
_x000D_
_x000D_


I liked @mate64's answer so I am going to reuse that with slight modifications to create a slide down and up animations below:

_x000D_
_x000D_
var $slider = document.getElementById('slider');_x000D_
var $toggle = document.getElementById('toggle');_x000D_
_x000D_
$toggle.addEventListener('click', function() {_x000D_
    var isOpen = $slider.classList.contains('slide-in');_x000D_
_x000D_
    $slider.setAttribute('class', isOpen ? 'slide-out' : 'slide-in');_x000D_
});
_x000D_
#slider {_x000D_
    position: absolute;_x000D_
    width: 100px;_x000D_
    height: 100px;_x000D_
    background: blue;_x000D_
    transform: translateY(-100%);_x000D_
    -webkit-transform: translateY(-100%);_x000D_
}_x000D_
_x000D_
.slide-in {_x000D_
    animation: slide-in 0.5s forwards;_x000D_
    -webkit-animation: slide-in 0.5s forwards;_x000D_
}_x000D_
_x000D_
.slide-out {_x000D_
    animation: slide-out 0.5s forwards;_x000D_
    -webkit-animation: slide-out 0.5s forwards;_x000D_
}_x000D_
    _x000D_
@keyframes slide-in {_x000D_
    100% { transform: translateY(0%); }_x000D_
}_x000D_
_x000D_
@-webkit-keyframes slide-in {_x000D_
    100% { -webkit-transform: translateY(0%); }_x000D_
}_x000D_
    _x000D_
@keyframes slide-out {_x000D_
    0% { transform: translateY(0%); }_x000D_
    100% { transform: translateY(-100%); }_x000D_
}_x000D_
_x000D_
@-webkit-keyframes slide-out {_x000D_
    0% { -webkit-transform: translateY(0%); }_x000D_
    100% { -webkit-transform: translateY(-100%); }_x000D_
}
_x000D_
<div id="slider" class="slide-in">_x000D_
    <ul>_x000D_
        <li>Lorem</li>_x000D_
        <li>Ipsum</li>_x000D_
        <li>Dolor</li>_x000D_
    </ul>_x000D_
</div>_x000D_
_x000D_
<button id="toggle" style="position:absolute; top: 120px;">Toggle</button>
_x000D_
_x000D_
_x000D_


USE THIS FOR RIGHT TO LEFT SLIDING :

HTML:

   <div class="nav ">
       <ul>
        <li><a href="#">HOME</a></li>
        <li><a href="#">ABOUT</a></li>
        <li><a href="#">SERVICES</a></li>
        <li><a href="#">CONTACT</a></li>
       </ul>
   </div>

CSS:

/*nav*/
.nav{
    position: fixed;
    right:0;
    top: 70px;
    width: 250px;
    height: calc(100vh - 70px);
    background-color: #333;
    transform: translateX(100%);
    transition: transform 0.3s ease-in-out;

}
.nav-view{
    transform: translateX(0);
}
.nav ul{
    margin: 0;
    padding: 0;
}
.nav ul li{
    margin: 0;
    padding: 0;
    list-style-type: none;
}
.nav ul li a{
    color: #fff;
    display: block;
    padding: 10px;
    border-bottom: solid 1px rgba(255,255,255,0.4);
    text-decoration: none;
}

JS:

  $(document).ready(function(){
  $('a#click-a').click(function(){
    $('.nav').toggleClass('nav-view');
  });
});