From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
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
Pertamax…first comment 😀
Nossa muito bom.. o layout
WOW!!! Beautiful effects 🙂
Amazing work once again! This is great!
Your work is awesome, as usual. (There are two open tags inside the . I assume the second one is supposed to be closed.)
thank you, so much
Awesome gird technique and effect. There’s a small bug in Chrome. If you attempt to scroll during the expanding effect animation, parts of the grid will be visible when “view-single” class is active.
Wow. Really nice.. Clean.
Very nice… it looks like https://voll.digital/
Cool, actually that looks more like this one: http://tympanus.net/Development/3DGridEffect/ 🙂
Good looking, but just for fun!
Without ajax navigation : the content text is not a really load, all in one and the same page.
From the article: “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).” Obviously you would need to implement that. Cheers.
Awesome really amazing work
Nice job!
this is really awesome effect, although I am not dynamic website designer so I don’t know when I will use it may be someone to make tutorial on this to help out, but the work you have done is relly loving
Ow, Nice work!
This is excellent. What is your inspiration behind these designs? How do you come up with these ideas?
Hi , It’s nice , but i want use it on mvc , but i can’t get the same as this , i change and replace css and JS but not the same as your page ,
can you put it on mvc project
This is bloody brilliant! Thanks!
How do I target specific content__item classes? I’m trying to utilize the dummy “next” and “back” buttons in demo2, but am having a tough time deciphering the logic that connects the grid_item classes with specific content_item classes.
https://github.com/chinchang/cta.js
I have the same problem. help
I always wonder how beautiful your imagination is! Thanks for being there to inspire us Mary.
Great work !
It should be perepard for WordPress too 🙂
This is way better than many or most actual blogs or magazines. I like it, maybe I’m going to use this in a personal project. Thanks for sharing
That’s very good idea & code here.
But I got a bug. I don’t know it can be resolved or not. When click on a blog & it goes to expand, at that time scroll down. Bottom part gets overlap with an expanded blog area.
This would be great ported to WordPress.
Great article.
A library that can help do such effects and much more: http://kushagragour.in/lab/ctajs/
Oi Mary Lou, só vim dizer que esse website é fantástica! Sou um Designer Gráfico do Brasil e isso me ajuda tanto na minha relação com os programadores. Obrigado por compartilhar sua sabedoria, está ajudando a mim e outras centenas de milhares de pessoas <3
Freaking sexy as hell… love it. Bookmarked.
Great! Bookmarked.
I going to use this in my personal project. But its hard to debug. All the css crashed and page is blank.
Oops …
Awesome Article for Blogs i like it
Hey, great article and awesome idea…
According to me It would be perfect if there was a different url for each post…and not only one url for the whole blog, this is a huge limit 🙁
Is it possible to fix it mantaining your concept ?
Great Idea! I was just working on a similar concept for a SAP (Single Page Application).
Ivan you can do that by using the
window.location.hashchange
binded to the.on('click', function()...
event in JQuery. At least without messing with the original concept.Very nice effect. The major two issues are mentioned already – scrolling and no linking to an individual blog post.
it’ll be awesome just simple awesome believe me awesome if it can load page via ajax with same effect.
Beautiful layout! I definitely want to use this. Pretty simple stuff. I love clean sites like this.
Great work!. But i have one question i still tested in android webview but there are someting went wrong.
You’re the goddess of web design. You know that.
Any chance you could make a post with say a list of your tutorials from easiest to hardest? I’m finding most of the things you post to be way beyond me and I want to work up to them.
Thanks
Just removed classie with jQuery and added Ajax loading of the Article content 🙂 If anybody interested:
https://github.com/marifrahman/AnimatedGridLayout
Does not work
@gmal, you have to open it via server, not just opening his index.html it does work.
@marifrahman Thank you so much for sharing. Perfect. Saved me a lot of time. I’ll be adding a filterable, searchable grid and integrating into WordPress as a single page app. Will post link when done. You’re awesome and your code gave me a super start. Showing some love from New Orleans.
How would I go about adding different background images to each grid element? Would it be better to do it through the CSS or HTML ?
Awesome work !
Um loving it… Guess I’m gonna implement it on my blog soon…
Hello! One man is selling your work like its own http://www.lpkurs.ru/neopages.html#
i wan to integreate with angular js but after integreated could not showed article section ,have you any idea?
Muito bom mesmo, adorei ^.^
Great Tutorial, really love it – as I also love all the other tutorials from you guys.
But would it be possible to have such kind of Quickfacts for your tutorials? About Browser Compatibility, used technologies and such? That would be really awesome.
Many thanks and keep up the good work.
Hi Mary Lou, thank you for that great work!
I just managed to connect this code to my Blogspot feed and build a site from this.
Works very well. Love the concept.
Nico
Me again… I see that in Firefox there is an issue with the close button due to a very long delay until the closing sequence starts… Any idea how to solve this?
Nice Effect. Any idea how to make the next previous to work ? I’m not good in jquery 🙂
Integrate this code into a wordpress theme and use wordpress’ next/previous code.
how to set our footer fixed because if i use this grid layout then sidebar animated layout move over the footer and also tell me how to open the content in full screen in right side
Hi, i was going through your code on main.js, one thing i didn’t understand is how, the placeholder expands when you add transform’s translate3d style on placeholder div under setTimeout function ? Basically i couldn’t get how it helps on expanding the div when there is no code to expand the div.. here is the code snippet that i didn’t understand under main.js
setTimeout(function() { // expands the placeholder dummy.style.WebkitTransform = 'translate3d(-5px, ' + (scrollY() - 5) + 'px, 0px)'; dummy.style.transform = 'translate3d(-5px, ' + (scrollY() - 5) + 'px, 0px)'; // disallow scroll window.addEventListener('scroll', noscroll); }, 25);
Suggest the upper right corner of the button to turn a few laps, the color can be set into a green, the current closure is really not so conspicuous.
While looking at this, I noticed the content loads in the same order it is in the Grid Area as the Content Area. Meaning Grid Item 3 loads Content Item 3.
Is there anyway this can be changed to have ID’s so it does not matter the order they are in the Content or Grid area? Looking into using this Grid however I want a Sort option and that would not work with the current set up.
I can’t download 🙁
Hi, I found bug in you’r example.
When I choose an article and datas is loaded, I click into a text to focus there, then I trying navigate by keyboard and press button “END” firstable, then press button “HOME”, then I close current article by button “X” (close). And when I going back to contents the hover effect animate very slow… Well I choose another any article and then I trying navigate by mouse, down and up, and when I return to contents page hover effect works normal.