Grid Item Animation Layout

A responsive, magazine-like website layout with a grid item animation effect that happens when opening the content.

GridItemAnimation

View demo Download source

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).

GridItemAnimation_02

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.

Please note that this layout uses some modern techniques that involve viewport units, transitions, flexbox and other properties that will only work in modern browsers.

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.

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.

GridItemAnimation_01

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

View demo Download source

Previous:
Next:

Tagged with:

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://www.codrops.com

Related Articles

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start learning CSS now.

Feedback 80

  1. 5

    Your work is awesome, as usual. (There are two open tags inside the . I assume the second one is supposed to be closed.)

  2. 7

    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.

  3. 11

    Good looking, but just for fun!
    Without ajax navigation : the content text is not a really load, all in one and the same page.

    • 12

      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.

  4. 15

    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

  5. 17

    This is excellent. What is your inspiration behind these designs? How do you come up with these ideas?

  6. 18

    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

  7. 20

    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.

Follow this discussion

Leave a Comment