From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
Today we’d like to share a simple animated grid layout with you. The responsive layout has a sidebar and grid items that animate to a larger content area when clicked. In the first demo the content area fills the grid (inspired by a concept by Virgil Pana) and in the second demo, the whole layout moves to the left while the grid item is expanding (inspired by this Dribbble shot by Sam Thibault).
The expanding element (which is a dummy element and not the grid item itself) is not animating in width and height but instead its original dimensions are already of the expanded size and we simply scale it down initially. By setting classes, we control the transitions of all the elements: the grid item elements’ disappearance and the content elements’ appearance (and vice versa when we close an opened content panel).
The layout is responsive down to mobile using a media query technique that involves setting the breakpoints based on the grid item size and the sidebar. For this we use Sass, which allows us to set these kind of variables easily. The approach we are using here is mainly mobile-first, but we also do some specific restructuring for small screens.
The second demo is a bit more experimental and it might not behave as expected in all browsers. Internet Explorer seems to have some issues with transitions on transforms that use calc().
This layout is focused on the expansion effect of the grid item and many elements are simple dummies (the loader, the filter in the top bar and the “load more” in the footer of the grid).
The main markup looks as follows:
<div class="container">
<button class="menu-toggle" id="menu-toggle" ><span>Menu</span></button>
<div class="sidebar" id="theSidebar" >
<button class="close-button fa fa-fw fa-close"></button>
<!-- ... other elements ... -->
</div>
<div class="main" id="theGrid" >
<section class="grid">
<header class="top-bar">
<!-- header elements -->
</header>
<a class="grid__item" href="#">
<!-- preview elements -->
</a>
<a class="grid__item" href="#">
<!-- preview elements -->
</a>
<!-- ... -->
<footer class="page-meta">
<!-- ... -->
</footer>
</section><!-- /grid -->
<section class="content">
<div class="scroll-wrap">
<article class="content__item">
<!-- content -->
</article>
<article class="content__item">
<!-- content -->
</article>
<!-- ... -->
</div>
<button class="close-button"><i class="fa fa-close"></i><span>Close</span></button>
</section><!-- /content -->
</div><!-- /main -->
</div><!-- /container -->
The Sass files of this project are divided into a main style file and two partials, one for the base styles and one for the media queries. Each of the demos will have a unique style Sass file (style1.scss and style2.scss) where we initiate some variable and redefine some styles if necessary (as in demo 2). There are many ways of organizing your project in Sass; this was one convenient way to do it for these two demos. If you’d like to use one of them, make sure to refactor your style declarations. If you are not familiar with Sass, you can simply use and adjust the generated CSS files.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
An example for the main demo Sass file is as follows:
$item_width: 300px;
$sidebar_width: 300px;
$color_primary: #fafafa;
$color_secondary: #fff;
$color_link: #81c483;
$anim-time: 0.5s;
@import "base";
@import "mediaqueries";
The variables needed in the base and the media queries Sass files are defined here.
The media query breakpoints are defined by the amount of items we want to be visible in the grid and the sidebar (no prefixes shown):
/* Viewport sizes based on column number and sidebar */
$viewport_xs: $item_width + $sidebar_width; /* 1 column */
$viewport_s: $item_width * 2 + $sidebar_width; /* 2 columns */
$viewport_m: $item_width * 3 + $sidebar_width; /* 3 columns */
$viewport_l: $item_width * 4 + $sidebar_width; /* 4 columns */
$viewport_xl: $item_width * 5 + $sidebar_width; /* 5 columns */
$viewport_xxl: $item_width * 6 + $sidebar_width; /* 6 columns */
@media screen and (min-width: $viewport_xs) {
html,
body,
.container,
.main {
height: 100vh;
}
.main {
height: 100%;
margin-left: $sidebar_width;
}
.content__item {
font-size: 1em;
}
.grid__item {
padding: 45px 45px 30px;
}
}
@media screen and (min-width: $viewport_s) {
.grid {
display: flex;
flex-wrap: wrap;
}
/* 2 columns */
.grid__item {
width: 50%;
border: none;
}
.grid__item::before {
top: 5px;
right: 5px;
bottom: 5px;
left: 5px;
border: 1px solid rgba(74,74,74,0.075);
transition: opacity 0.3s;
}
.grid__item:hover::before,
.grid__item:focus::before {
border: 3px solid rgba(129,196,131,0.5);
}
.grid__item--loading.grid__item::before {
opacity: 0;
}
}
@media screen and (min-width: $viewport_m) {
/* 3 columns */
.grid__item {
width: 33.333%;
}
}
@media screen and (min-width: $viewport_l) {
/* 4 columns */
.grid__item {
width: 25%;
}
}
@media screen and (min-width: $viewport_xl) {
/* 5 columns */
.grid__item {
width: 20%;
}
}
@media screen and (min-width: $viewport_xxl) {
/* 6 columns */
.grid__item {
width: 16.66%;
}
}
/* small screen changes for sidebar (it becomes an off-canvas menu) */
@media screen and (max-width: $viewport_xs - 1px) {
.sidebar {
transform: translate3d(-100%,0,0);
}
.sidebar.sidebar--open {
transform: translate3d(0,0,0);
}
.sidebar.sidebar--open ~ .main {
pointer-events: none;
}
.top-bar {
padding: 22px 15px 10px 60px;
}
.menu-toggle {
display: inline-block;
}
.sidebar .close-button {
opacity: 1;
top: 15px;
right: 15px;
pointer-events: auto;
}
.title--full {
font-size: 2em;
}
.content__item {
padding: 80px 20px 40px;
}
.close-button {
padding: 10px 20px;
}
.close-button::before {
content: '';
position: absolute;
top: 0;
right: 0;
background: $color_secondary;
border-bottom: 1px solid $color_primary;
width: 100vw;
height: 50px;
pointer-events: none;
z-index: -1;
}
}
This technique can come in handy when dealing with grid layouts. Optimally, we’d not have that last media query at all if we want to strictly follow a mobile-first approach. But since these styles are exclusively valid only for small screens, we don’t want to be redefining and overwriting styles for larger screens.
Have a look at the layout and the effect and dig into the source, we really hope you find this template useful and inspiring!
Credits: Mockups by Firmbee
How do I change the green border that appears around grid items upon hovering? I’ve been digging through the code for a while and have not had any luck. Please advise!
Thanks for sharing this tutorial.
The result looks incredible!
I developed a project named chewing-grid.css that use flexbox too.
You should use it for this kind of grid layout, it will save you from writing the media-queries.
The cell will automatically adapt the column number according to 3 constraints: the maximum number of columns, the minim and maximum card width.
Cheers,
Thomas.
I really can’t say much about this design. It’s extremely sick!!!WOW
Who is Mary Lou???
Truly Amazing. I will use this concept on my personal blog theme. Again thanks for sharing.
Hello I really love your work and can’t say enough about it but I always have trouble trying to get your scripts to work. Is there any easy tutorial you might have to help m e out. I use WordPress for all my build sites. Thanks so much
Hello.
I liked this layout, can I built wordpress theme with this layout. Of cource it will be free..
How would you make the grids dynamic so it reads the data from a DB and displays the grid items dynamically based on the number of records in a table?
Nice demo! I was trying to create similar grid with ‘scale’ on click effect using Highslide and Gridifier libs.
Hi – I need some help on another article you’ve written (http://tympanus.net/codrops/2012/01/02/fullscreen-background-image-slideshow-with-css3/) but I can’t comment on it as they are closed
What would I have to do to make the animation work for a background on a div / element rather than the whole screen ?
I want to have this animation working on a jumbotron header
many thanks – love the original article
Hi there! Thanks for sharing this with us. I used your code to create my WordPress portfolio. It goes very well but sometimes, when I load project, on my sidebar images flash for a sec. Like when the grid is moving to the left and it happens a moment before new sidebar is loaded. It happens just sometimes, I have no idea why.
I used second version of your project and you can check my site here http://valeka.net/
Thanks!
@Valeka Your websites looks cool. Is it in WordPress?
hi Valeka,
i have in issue with this trying to create a WP theme from this beautiful template. i made the grid items to be displayed as wp posts but when i click on an item (post) i want it to send me to the post content (single.php, permalink) but the js animations (basically main.js) dosent work at all. heres my question at stackoverflow: https://stackoverflow.com/questions/45803321/uncaught-typeerror-cannot-read-property-queryselectorall-of-null-html-to-wo
i would appreciate ur help a lot!
This is a fantastic example of a responsive grid with hidden content. Has anyone been able to get a filter to work with it, perhaps Shuffle.js?
Hi.Earlier I’d asked if anyone had a filter running on this Grid Item Animation Layout. I tried Shuffle.js without luck. But I just found this one that does seem to work. Very simple to setup. https://github.com/geedmo/portfilter
Further to my suggestion of a filter JS. I found this one also works. Just pay attention to adapting it to the layout (pretty easy), and its purpose (it has some UX challenges depending on what you want the user to filter, but really powerful): http://wch.io/projects/tagsort/
Is there a way to use this template but open to other pages? (Instead of having the articles all be on one html page)
hey i would like to know how can i put a logo when its on mobile view in the article page where theres the menu and the close button can’t figure it out not really into javaScript but all in all fantastic design. please help if u can 🙂 thanks!
Great , awesome work . Anyone figure out the back button function
You are really crazy. Awesome design and animation. OMG !!!!
Very sexy grid. Thanks, I am definitely using this concept for my portfolio site.