There will be cases when you need to display side content (a notification, a user profile information...), and this content doesn't fit into a tooltip. You may create a new page and link to it, but, when possible, it's wise to avoid a page refresh. In these cases a panel that slides in from the side can be a good UX solution. It's fast, can be easily animated using CSS3 transitions, and it's something users are used to see (think how many times this effect is used in native mobile apps).

A lot of websites are using this solution, take a look at Feedly and the Spotify web player just to mention a couple.

Now let's take a look at the code!

👋 A new version of this component is available. Download now →.

Creating the structure

The HTML structure is super simple. We created a <header> , supposed to be fixed while you scroll through the content, a separate <div> for the panel content, and wrapped all inside a .cd-panel div. The <main> element will contain our main content.

<main class="cd-main-content"> <!-- your main content here --> </main> <div class="cd-panel cd-panel--from-right js-cd-panel-main"> <header class="cd-panel__header"> <h1>Title Goes Here</h1> <a href="#0" class="cd-panel__close js-cd-close">Close</a> </header> <div class="cd-panel__container"> <div class="cd-panel__content"> <!-- your side panel content here --> </div> <!-- cd-panel__content --> </div> <!-- cd-panel__container --> </div> <!-- cd-panel -->

Adding style

Couple of hints about the CSS. We applied a CSS3 transformation - precisely we used the translateX property - to the .cd-panel__container to make it slide-in. Using a transformation instead of animating the position left/right values is better in terms of performance.

The header is animated separately from the panel content (for the <header> we animate the translateY value instead).

.cd-panel { /*...*/ visibility: hidden; transition: visibility 0s 0.6s; } .cd-panel.cd-panel--is-visible { visibility: visible; transition: visibility 0s 0s; } .cd-panel__header { /*...*/ position: fixed; top: 0; width: 90%; height: 50px; transition: transform 0.3s 0s; transform: translateY(-50px); } .cd-panel--from-right .cd-panel__header { right: 0; } .cd-panel--from-left .cd-panel__header { left: 0; } .cd-panel--is-visible .cd-panel__header { transition: transform 0.3s 0.3s; transform: translateY(0px); } .cd-panel__container { /*...*/ position: fixed; width: 90%; height: 100%; top: 0; transition: transform 0.3s 0.3s; } .cd-panel--from-right .cd-panel__container { right: 0; transform: translate3d(100%, 0, 0); } .cd-panel--from-left .cd-panel__container { left: 0; transform: translate3d(-100%, 0, 0); } .cd-panel--is-visible .cd-panel__container { transform: translate3d(0, 0, 0); transition-delay: 0s; }

One more point some of you may find interesting is the transition-delay property. When you animate elements on a web page, if you create some delays, or use different transition/animation durations, things get more interesting. That's when the transition-delay comes in handy. In this resource, for example, the header slides in after the panel content, and pops-out before it. If you want to explore some concepts about animations and transitions, take a look at the Google Material documentation.

Important note: if you change the class name applied to the .cd-panel from .cd-panel--from-right to .cd-panel--from-left , the panel will slide in (guess what?) from the left.

Events Handling