Split Layout

A template for a split layout with two sides. When clicking on a half in the initial view, the layout moves into the respective direction with some transition effects.

This Blueprint is a layout with two sides, sometimes seen in portfolio websites of couples and partners. The idea is to show an initial two-sided view and when clicking on a side, the whole page transitions into the respective direction. The individual page of the selected person is shown.

The Blueprint comes with some example media queries and a second demo where the disappearing side scales down. It will work in modern browsers (from IE9 on).

The HTML

<div class="container">
	<div id="splitlayout" class="splitlayout">
		<div class="intro">
			<div class="side side-left">
				<div class="intro-content">
					<div class="profile"><img src="img/profile1.jpg" alt="profile1"></div>
					<h1><span>Toby Blue </span><span>Web Designer</span></h1>
				</div>
				<div class="overlay"></div>
			</div>
			<div class="side side-right">
				<div class="intro-content">
					<div class="profile"><img src="img/profile2.jpg" alt="profile2"></div>
					<h1><span>Amy White </span><span>Web Developer</span></h1>
				</div>
				<div class="overlay"></div>
			</div>
		</div><!-- /intro -->
		<div class="page page-right page-large">
			<div class="page-inner">
				<section>
					<!-- content -->
				</section>
				<section>
					<!-- content -->
				</section>
				<!-- ... -->
			</div><!-- /page-inner -->
		</div><!-- /page-right -->
		<div class="page page-left page-fill">
			<div class="page-inner">
				<!-- ... -->
			</div><!-- /page-inner -->
		</div><!-- /page-left -->
		<a href="#" class="back back-right" title="back to intro">→</a>
		<a href="#" class="back back-left" title="back to intro">←</a>
	</div><!-- /splitlayout -->
</div><!-- /container -->

The CSS

html, body, 
.container {
	position: relative;
	width: 100%;
	height: 100%;
}

body {
	overflow-y: scroll;
	background: #333;
}

.splitlayout {
	position: relative;
	overflow-x: hidden;
	min-height: 100%;
	width: 100%;
}

/* Intro sides */
.side {
	position: fixed;
	top: 0;
	z-index: 100;
	width: 50%;
	height: 100%;
	text-align: center;
	-webkit-backface-visibility: hidden;
}

.open-left .side,
.open-right .side {
	cursor: default;
}

.overlay {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 499;
	visibility: hidden;
	width: 100%;
	height: 100%;
	opacity: 0;
}

.side-left .overlay {
	background: rgba(0,0,0,0.7);
}

.side-right .overlay {
	background: rgba(0,0,0,0.3);
}

.side-left {
	left: 0;
	background: #47a3da;
	color: #fff;
	outline: 1px solid #47a3da; /* avoid gap */
}

.side-right {
	right: 0;
	background: #fff;
	color: #47a3da;
	outline: 1px solid #fff; /* avoid gap */
}

/* Intro content, profile image and name, back button */
.intro-content {
	position: absolute;
	top: 50%;
	left: 50%;
	padding: 0 1em;
	width: 50%;
	cursor: pointer;
	-webkit-transform: translateY(-50%) translateX(-50%);
	transform: translateY(-50%) translateX(-50%);
}

.profile {
	margin: 0 auto;
	width: 140px;
	height: 140px;
	border-radius: 50%;
	background: #47a3da;
}

.profile img {
	max-width: 100%;
	border-radius: 50%;
	opacity: 0.6;
}

.intro-content h1 > span {
	display: block;
	white-space: nowrap;
}

.intro-content h1 > span:first-child {
	font-weight: 300;
	font-size: 2em;
}

.intro-content h1 > span:nth-child(2) {
	position: relative;
	margin-top: 0.5em;
	padding: 0.8em;
	text-transform: uppercase;
	letter-spacing: 1px;
	font-size: 0.8em;
}

.intro-content h1 > span:nth-child(2):before {
	position: absolute;
	top: 0;
	left: 25%;
	width: 50%;
	height: 2px;
	background: #fff;
	content: '';
}

.side-right .intro-content h1 > span:nth-child(2):before {
	background: #47a3da;
}

.back {
	position: fixed;
	top: 2.6em;
	z-index: 500;
	display: block;
	visibility: hidden;
	width: 50px;
	height: 50px;
	border-radius: 50%;
	color: #47a3da;
	text-align: center;
	font-size: 22px;
	line-height: 44px;
	opacity: 0;
	pointer-events: none;
}

.mobile-layout .back { /* fixed positioning will make this not clickable after scrolling on some mobile devices */
	position: absolute;
}

.back-left {
	left: 12.5%;
	-webkit-transform: translateX(-50%);
	transform: translateX(-50%);
}

.back-right {
	right: 12.5%;
	-webkit-transform: translateX(50%);
	transform: translateX(50%);
	color: #fff;
}

.open-right .back-left,
.open-left .back-right {
	visibility: visible;
	opacity: 1;
	-webkit-transition-delay: 0.3s;
	transition-delay: 0.3s;
	pointer-events: auto;
}

.back:hover {
	color: #ddd;
}

/* Pages */
.page {
	position: relative;
	top: 0;
	overflow: auto;
	min-height: 100%;
	width: 75%;
	height: auto;
	font-size: 1.4em;
	-webkit-backface-visibility: hidden;
}

.page-right {
	left: 25%;
	outline: 5px solid #ecf0f1; /* avoid rounding gaps */
	background: #ecf0f1;
	color: #97a8b2;
	-webkit-transform: translateX(100%);
	transform: translateX(100%);
}

.splitlayout.open-right {
	background: #ecf0f1;
}

.page-left {
	left: 0;
	outline: 5px solid #34495e; /* avoid rounding gaps */
	background: #34495e;
	color: #fff;
	text-align: right;
	-webkit-transform: translateX(-100%);
	transform: translateX(-100%);
}

.splitlayout.open-left {
	background: #34495e;
}

/* Inner page content */
.page-inner {
	padding: 2em;
}

.page-inner section {
	padding-bottom: 1em;
}

.page-inner h2 {
	margin: 0 0 1em 0;
	font-weight: 300;
	font-size: 2.4em;
}

.page-inner p {
	font-weight: 300;
	font-size: 1.2em;
}

/* All transitions */
.side,
.page {
	-webkit-transition: -webkit-transform 0.6s;
	transition: transform 0.6s;
}

.overlay {
	-webkit-transition: opacity 0.6s, visibility 0.1s 0.6s;
	transition: opacity 0.6s, visibility 0.1s 0.6s;
}

.intro-content {
	-webkit-transition: -webkit-transform 0.6s, top 0.6s;
	transition: transform 0.6s, top 0.6s;
}

.intro-content h1,
.back {
	-webkit-transition: opacity 0.3s;
	transition: opacity 0.3s;
}

/* Open and close */

/* We need to set the position and overflow for the respective page scroll */
.reset-layout .page,
.splitlayout.open-right .page-left,
.splitlayout.open-left .page-right,
.splitlayout.close-right .page-left,
.splitlayout.close-left .page-right {
	position: absolute;
	overflow: hidden;
	height: 100%;
}

.splitlayout.open-right .page-right,
.splitlayout.open-left .page-left {
	position: relative;
	overflow: auto;
	height: auto;
}

.open-right .side-left .overlay,
.open-left .side-right .overlay {
	visibility: visible;
	opacity: 1;
	-webkit-transition: opacity 0.6s;
	transition: opacity 0.6s;
}

/* Right side open */
.open-right .side-left {
	-webkit-transform: translateX(-60%);
	transform: translateX(-60%);
}

.open-right .side-right {
	z-index: 200;
	-webkit-transform: translateX(-150%);
	transform: translateX(-150%);
}

.close-right .side-right {
	z-index: 200;
}

.open-right .side-right .intro-content {
	-webkit-transform: translateY(-50%) translateX(0%) scale(0.6);
	transform: translateY(-50%) translateX(0%) scale(0.6);
}

.open-right .page-right {
	-webkit-transform: translateX(0%);
	transform: translateX(0%);
}

/* Left side open */
.open-left .side-right {
	-webkit-transform: translateX(60%);
	transform: translateX(60%);
}

.open-left .side-left {
	z-index: 200;
	-webkit-transform: translateX(150%);
	transform: translateX(150%);
}

.close-left .side-left {
	z-index: 200;
}

.open-left .side-left .intro-content {
	-webkit-transform: translateY(-50%) translateX(-100%) scale(0.6);
	transform: translateY(-50%) translateX(-100%) scale(0.6);
}

.open-left .codropsheader {
	opacity: 0;
	visibility: hidden;
	-webkit-transition: opacity 0.3s, visibility 0.1s 0.3s;
	transition: opacity 0.3s, visibility 0.1s 0.3s;
}

.open-left .page-left {
	-webkit-transform: translateX(0%);
	transform: translateX(0%);
}

/* Media Queries */
@media screen and (max-width: 83em) {
	.intro-content { font-size: 60%; }
}

@media screen and (max-width: 58em) {
	body { font-size: 90%; }
}

@media screen and (max-width: 49.4375em) {
	.open-right .side-right {
		-webkit-transform: translateX(-175%);
		transform: translateX(-175%);
	}

	.open-right .side-left {
		-webkit-transform: translateX(-100%);
		transform: translateX(-100%);
	}

	.open-left .side-right {
		-webkit-transform: translateX(100%);
		transform: translateX(100%);
	}

	.open-left .side-left {
		-webkit-transform: translateX(175%);
		transform: translateX(175%);
	}

	.page {
		width: 100%;
	}

	.page-right {
		left: 0;
		padding-left: 15%;
	}

	.page-left {
		padding-right: 15%;
	}

	.intro-content {
		width: 100%;
	}

	.open-right .side-right .intro-content {
		top: 100%;
		-webkit-transform: translateY(-150px) translateX(-12.5%) scale(0.5);
		transform: translateY(-150px) translateX(-12.5%) scale(0.5);
	}

	.open-left .side-left .intro-content {
		top: 100%;
		-webkit-transform: translateY(-150px) translateX(-87.5%) scale(0.5);
		transform: translateY(-150px) translateX(-87.5%) scale(0.5);
	}

	.open-right .intro-content h1,
	.open-left .intro-content h1 {
		opacity: 0;
	}

	.back-left {
		left: 6.25%;
	}

	.back-right {
		right: 6.25%;
	}
}

@media screen and (max-width: 42.5em) {
	body { font-size: 80%; }
	.intro-content { font-size: 50%; }
}

@media screen and (max-height: 41.125em) {
	.intro-content {
		-webkit-transform: translateY(-25%) translateX(-50%);
		transform: translateY(-25%) translateX(-50%);
	}
}

@media screen and (max-width: 39.375em) {
	.intro-content .profile { -webkit-transform: scale(0.5); transform: scale(0.5); }
}

@media screen and (max-width: 320px) {
	body { font-size: 70%; }
}

Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.

The JavaScript

/**
 * cbpSplitLayout.js v1.0.0
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
(function() {

	'use strict';

	// http://stackoverflow.com/a/11381730/989439
	function mobilecheck() {
		var check = false;
		(function(a){if(/(android|ipad|playbook|silk|bbd+|meego).+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
		return check;
	}

	var splitlayout = document.getElementById( 'splitlayout' ),
		leftSide = splitlayout.querySelector( 'div.intro > div.side-left' ),
		rightSide = splitlayout.querySelector( 'div.intro > div.side-right' ),
		pageLeft = splitlayout.querySelector( 'div.page-left' ),
		pageRight = splitlayout.querySelector( 'div.page-right' ),
		eventtype = mobilecheck() ? 'touchstart' : 'click',
		transEndEventNames = {
			'WebkitTransition': 'webkitTransitionEnd',
			'MozTransition': 'transitionend',
			'OTransition': 'oTransitionEnd',
			'msTransition': 'MSTransitionEnd',
			'transition': 'transitionend'
		},
		transEndEventName = transEndEventNames[Modernizr.prefixed( 'transition' )];

	function init() {
		if( mobilecheck() ) {
			classie.add( splitlayout, 'mobile-layout' );
		}
		classie.add( splitlayout, 'reset-layout' );

		leftSide.querySelector( 'div.intro-content' ).addEventListener( eventtype, function( ev ) {
			reset();
			classie.add( splitlayout, 'open-left' );
		} );

		rightSide.querySelector( 'div.intro-content' ).addEventListener( eventtype, function( ev ) {
			reset();
			classie.add( splitlayout, 'open-right' );
		} );

		// back to intro
		// after transition ends:
		var onEndTransFn = function() {
				this.removeEventListener( transEndEventName, onEndTransFn );
				classie.add( splitlayout, 'reset-layout' );
				document.body.scrollTop = document.documentElement.scrollTop = 0;
			},
			backToIntro = function( ev ) {
				ev.preventDefault();
				ev.stopPropagation();
				var dir = classie.has( ev.target, 'back-right' ) ? 'left' : 'right',
					page = dir === 'right' ? pageRight : pageLeft;
				classie.remove( splitlayout, 'open-' + dir );
				classie.add( splitlayout, 'close-' + dir );
				page.addEventListener( transEndEventName, onEndTransFn );
			};

		splitlayout.querySelector( 'a.back-left' ).addEventListener( eventtype, backToIntro );
		splitlayout.querySelector( 'a.back-right' ).addEventListener( eventtype, backToIntro );
	}

	function reset() {
		classie.remove( splitlayout, 'close-right' );
		classie.remove( splitlayout, 'close-left' );
		classie.remove( splitlayout, 'reset-layout' );
	}

	init();

})();

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

Fresh news, inspo, code demos, and UI animations—zero fluff, all quality. Make your Mondays and Thursdays creative!

Feedback 108

Comments are closed.
  1. Hi,

    Is it possible to have the page-left and page-right fullscreen?
    how it could be achieved?

    Thanks

  2. Used the wrong email in my last request (oops!). Anyway, have others received a copy of the WordPress .zip file from Hermes and successful got a WP installation working? If so, please share (I will be happy too also upon receipt of course). Email: abc@clearwater.limited

    Many thanks in advance to anyone who can assist. Andrew.

  3. Hello Mary Lou,

    Looking for something similar to this to basically go to 2 websites that have subdomains of my main domain, would it be able to work on top of WordPress, thanks in advance?

    Howard

  4. Hi,
    great job!
    I’d like to add on the top a fixed 100% width header. height 60px. It must be fixed even when I click for split

    how can i do?

    thanks
    m

  5. By the way to those who DO NOT WANT the layout to be 100% fixed.

    Change:

    .side { position:absolute; //this is fixed in the CSS given height:xx //to whatever height you need. }

    Now this will cause the layout to look weird when you open them for this you ought to add (preferably below line 295 for cascading purposes)

    .splitlayout.open-right .side { position: fixed; height:100%; }

  6. By the way to those who DO NOT WANT the layout to be 100% fixed.

    Change:

    .side { position:absolute; //this is fixed in the CSS given height:xx //to whatever height you need. }

    Now this will cause the layout to look weird when you open them, for this you ought to add (preferably below line 295 for cascading purposes)

    .splitlayout.open-right .side, .splitlayout.open-left .side { position: fixed; height:100%; } .splitlayout.open-right .page-right, .splitlayout.open-left .page-left { position:fixed; }

    And that should do it.

  7. By the way to those who DO NOT WANT the layout to be 100% fixed.

    Change:

    .side { position:absolute; //this is fixed in the CSS given height:xx //to whatever height you need. }

    Now this will cause the layout to look weird when you open them for this you ought to add (preferably below line 295 for cascading purposes)

    .splitlayout.open-right .side, .splitlayout.open-left .side { position: fixed; height:100%; } .splitlayout.open-right .page-right, .splitlayout.open-left .page-left { position:fixed; }

  8. Find it crappy that a site that focused on Web Design doesn’t confirm the user his/her post has been submitted. Had to wonder three times what happened. Seriously guys.

    Btw, on the last peace of code, add height:100% too.

    • Hi Marco, that’s your 20th comment on Codrops 🙂 The comment system never changed (when you submit, the comment appears in the conversation instantly). What’s going on, you’re having a bad day? Cheer up man, just people here too 🙂

    • ^^^ Pedro.

      Negativo. It doesn’t. When I submit the comment it scrolls to the top (address bar) and no comment appears. This is why I submit the comment like 3-4 times. There is no confirmation that my comment has been either submitted or denied. I am using Mac OSX and Firefox 41.0.2 but the issue is with the Javascript of WordPress that is supposed “scroll to” the comment that doesn’t appear.

    • Oh, and I am not having a bad day. Just bad moments ;). But seriously, the comment system doesn’t scroll to the comment.

  9. hi,

    I am quite new to wordpress and to coding in general, so, what i want you to tell me is how i can upload this theme to my localhost site. I clicked on “Download source”, uploaded the .zip file, but it says that “The theme is missing the style.css stylesheet.”. Can someone send me the correct .zip, or tell me how i can fix this problem?

    thanks in advance

  10. Anyone have any idea how to make the left and right landing areas unique urls? I have content either side of split screen and have linked pages off it. So for example I have a portfolio grid on one side, when I press a portfolio item it opens a single post page. When the user hits back it goes back to the splitscreen again instead of back to the side they picked. Anyone any ideas?! Would appreciate the help!

    Thanks everybody!! 😀

  11. I am using this split layout with in the div element ( width 12 cols ) to show up in one of the section of my webpage. But it is not functional with in inside the div. And also in the mobile size window width the background area is stretching as shown in the image2.

    image is attached here

    Code:
    HTML>>

    PRODUCTS and MARKETS

    <!– BOTH INTRO BOX STARTS HERE –>

    <!– Start of SIDE-LEFT INTRO –>
    <!– LEFT INTRO CONTENT here –>
    <!– PRODUCTS INTRO HERE –>
    BLAH BLAH INTRO TEXT AND IMAGE

    <!– PRODUCTS INTO ENDS –>
    <!– END OF LEFT INTRO CONTENT –>

    <!– End of side side-left –>

    <!– Start of SIDE-RIGHT INTRO –>
    <!– RIGHT INTRO CONTENT here –>
    <!– MARKETS INTRO HERE –>

    BLAH BLAH INTRO TEXT AND IMAGE HERE

    <!– MARKETS INTO ENDS –>
    <!– END OF RIGHT INTRO CONTENT –>

    <!– End of side side-right –>

    <!– END OF BOTH INTRO BOX –>

    <!–*//// INNER PAGES START HERE *\\\\\\\\\\ –>

    <!– //INNER Page-RIGHT :: MARKETS \\ –>

    BLAH BLAH INNER TEXT

    <!– /page-inner –>
    <!– /Inner page-right –>

    <!– END Page-RIGHT :: MARKETS \\ –>

    <!– //Page-LEFT :: PRODUCTS \\ –>

    BLAH BLAH INNER TEXT

    <!– /page-inner –>
    <!– /page-left –>
    <!– END Page-LEFT :: PRODUCTS \\ –>
    <a href=”#” title=”back to intro” rel=”nofollow”>MARKETS →</a>
    <a href=”#” title=”back to intro” rel=”nofollow”>← PRODUCTS</a>
    <!– /splitlayout –>
    <!– /container –>

    <!– End of Col-12 div –>

    CODE :
    CSS

    I have also added the following suggestions in the CSS as suggested by the user MARCO in his above comments : ”

    ” By the way to those who DO NOT WANT the layout to be 100% fixed.
    Change:
    .side {
    position:absolute; //this is fixed in the CSS given
    height:xx //to whatever height you need.
    }
    Now this will cause the layout to look weird when you open them for this you ought to add (preferably below line 295 for cascading purposes)
    .splitlayout.open-right .side, .splitlayout.open-left .side {
    position: fixed;
    height:100%;
    }
    .splitlayout.open-right .page-right, .splitlayout.open-left .page-left {
    position:fixed;
    height:100%;
    } ”

  12. hallo Mary Lou,

    is there any chance to get a wordpress theme of this beautiful concept?

    thanks
    mick