16
Aug
2014

Expanding panel on hover

Demo | Source

Resources

I worked on a project  where we implemented a similar panel slider for a landing page to the different sectors of the company. Here I’ve just used an X-Files theme for the demo.

We begin with the HTML markup for the page. In the head I’ve included a reset.css file to help solve inconsistencies between browsers. Then the CSS file for the kwicks plugin is added. I’ve included the Fonts CSS in the header but you could do it with javascript. Then we have the css for our own styles.

At the bottom we have the scripts for jQuery, Kwicks and our own script.js where the plugin will be initiated.


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Expanding Panel on hover</title>
        <link rel='stylesheet' type='text/css' href='css/reset.css' />
        <link rel='stylesheet' type='text/css' href='css/kwicks.css' />
        <link href='http://fonts.googleapis.com/css?family=Open+Sans:400,800,700,300' rel='stylesheet' type='text/css'>
        <link rel='stylesheet' type='text/css' href='css/style.css' />
    </head>
    <body>
        <div class="content">
            <header class="demo-header">
                <h1>Expanding Panels on hover</h1>
            </header>

            <div class="demo">               
            </div>
        </div>
        <script src="js/jquery-2.1.1.js"></script>
        <script src="js/kwicks.js"></script>
        <script src="js/script.js"></script>
    </body>
</html>

The code for the actual panels is just an unordered list with classes of “kwicks” and “kwicks-horizontal”, which tells the plugin that we want our panels to expand horizontally. The content inside the li can be anything you want but I’ll explain how the code below works.

.panel-content is just a container for our content. The .bg has two child div which are the background layers, one for the image and one to give the dark overlay when the panels are collapsed or normal.

.opening-text is the text that appears when the panels are in their normal state.
.hidden-text will appear when the panel is expanded.
.collapsed-header will be the heading that appears when the panels are in their collapsed state.
Include the code below within the .demo div.


<ul class='kwicks kwicks-horizontal'>
	<li id="mulder" class="mulder">
		<div class="panel-content">
			<div class="bg">
				<div class="bg-image">
					<img decoding="async" src="images/mulder.jpg" alt="Fox Mulder"/>
				</div>
				<div class="bg-overlay"></div>
			</div>

			<div class="opening-text">
				<strong>Special Agent</strong>
				<h2>Fox Mulder</h2>
				<span>+</span>
			</div>

			<div class="hidden-text">
				<strong>Special Agent</strong>
				<h2>Fox Mulder</h2>
				<p>A highly skilled FBI Special Agent who brought his often-criticized method of formulating unconventional theories to the X-files.</p>
			</div>
			<h1 class="collapsed-header">Fox Mulder</h1>
		</div>
	</li>
	<li id="scully" class="scully">
		<div class="panel-content">
			<div class="bg">
				<div class="bg-image">
					<img decoding="async" src="images/scully.jpg" alt="Dana Scully" />
				</div>
				<div class="bg-overlay"></div>
			</div>

			<div class="opening-text">
				<strong>Special Agent</strong>
				<h2>Dana Scully</h2>
				<span>+</span>
			</div>

			<div class="hidden-text">
				<strong>Special Agent</strong>
				<h2>Dana Scully</h2>
				<p>An FBI Special Agent and medical doctor with a background in hard science who brought her scientific expertise and perspective to the X-files.</p>
			</div>
			<h1 class="collapsed-header">Dana Scully</h1>
		</div>                   
	</li>
	<li id="skinner" class="skinner">
		<div class="panel-content">
			<div class="bg">
				<div class="bg-image">
					<img decoding="async" src="images/skinner.jpg" alt="Walter Skinner" />
				</div>
				<div class="bg-overlay"></div>
			</div>

			<div class="opening-text">
				<strong>Special Agent</strong>
				<h2>Walter Skinner</h2>
				<span>+</span>
			</div>

			<div class="hidden-text">
				<strong>Special Agent</strong>
				<h2>Walter Skinner</h2>
				<p>An Assistant Director in the Federal Bureau of Investigation after having served as a Marine in the United States Marine Corps when he was aged 18.</p>
			</div>
			<h1 class="collapsed-header">Walter Skinner</h1>
		</div>
	</li>
	<li id="krycek" class="krycek">
		<div class="panel-content">
			<div class="bg">
				<div class="bg-image">
					<img decoding="async" src="images/krycek.jpg" alt="Alex Krycek"/>
				</div>
				<div class="bg-overlay"></div>
			</div>

			<div class="opening-text">
				<strong>Special Agent</strong>
				<h2>Alex Krycek</h2>
				<span>+</span>
			</div>

			<div class="hidden-text">
				<strong>Special Agent</strong>
				<h2>Alex Krycek</h2>
				<p>Little is known about Krycek's early life or education, other than his parents were Cold War immigrants and that he is consequently in Russia.</p>
			</div>
			<h1 class="collapsed-header">Alex Krycek</h1>
		</div>
	</li>
</ul>

The first bit of CSS gives the panels a height of 450px and aligns the content to the center. I’ve also set cursor to pointer when hovering over the li's


.kwicks {
    width: 100%;
    height: 450px;
}
.kwicks li{
    height: 450px;
    text-align: center;
    cursor: pointer;
}

Next we position the contents of .panel-content absolutley and give the .bg the lowest z-index. .opening-text and .hidden-code will have a higher z-index as we want these to appear above the .bg-image and .bg-overlay divs. These also have a transition set on their opacity property with a delay to allow for the expanding of the panel. The duration is 0.5s which is important as it matches the speed in which the panels slide.


.bg, 
.bg-image, 
.bg-overlay,
.hidden-text,
.opening-text{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}
.bg {
    z-index: 0;
}

.hidden-text,
.opening-text {
    z-index: 1;
    transition: opacity ease-in-out 0.5s;
    transition-delay: 0.3s;
}

The .hidden-text will start off hidden until the panel is expanded. I’ve set a width to stop the text from starting off at 0px and growing to full width as it looks terrible. The .opening-text styles just set the font colour and adds padding to the top of the dive to push down the text.


.hidden-text{
    opacity: 0;
    visibility: hidden;
    text-align: left;
    width: 200px;
    left: 30px;
    top: 110px;
}

.opening-text {
    color: #ebe9e9;
    padding-top: 340px;
}
/* Specific styling to these panels */
.skinner .hidden-text{
    color: #fff;
    text-shadow: 1px 1px 1px #000;
    width: 240px;
}
.krycek .hidden-text{
    left: 340px;
}

The following is just styles for the text which is all basic stuff.


.hidden-text strong,
.opening-text strong {
    font-weight: 900;
    font-size: 16px;
    line-height: 24px;
}
.hidden-text h2,
.opening-text h2 {
    font-weight: 300;
    font-size: 34px;
    margin: 0;
    line-height: 36px;
}
.hidden-text p {
    font-weight: 400;
    font-size: 14px;
    line-height: 24px;
}
.opening-text strong {
    width: 200px;
    display: block;
    margin: 0 auto;
}
.opening-text h2 {
    width: 230px;
    display: block;
    margin: 0 auto;
}
.opening-text span {
    font-weight: 900;
    font-size: 48px;
    line-height: 30px;
    width: 200px;
    margin: 0 auto;
    display: block;
}

The .bg-image CSS just sets a transition on the transform property. Again here the duration matches the time it takes for the panel to slide.

The .bg-overlay has a background colour of black with 70% alpha and a transition on the opacity property for a smooth transition when fading out.


.bg-image {
    transition: transform ease-in-out 0.5s;
}
.bg-overlay {
    background: rgba(0,0,0,0.7);
    transition: opacity  ease-in-out 0.3s;
    opacity: 1;
}

The next part of this will depend on the images that you use. This positions the images with each character in view when the panels are in the normal state. You could change any of the values for transform for different effects. I’m just setting the translate X value to pull the character into view.


.mulder .bg-image {
    -webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(-335px, 0);
    -moz-transform: rotate(0deg) scale(1) skew(0deg) translate(-335px, 0);
    -o-transform: rotate(0deg) scale(1) skew(0deg) translate(-335px, 0);
    -ms-transform: rotate(0deg) scale(1) skew(0deg) translate(-335px, 0);
    transform: rotate(0deg) scale(1) skew(0deg) translate(-335px, 0);
}
.scully .bg-image{
    -webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(-285px, 0);
    -moz-transform: rotate(0deg) scale(1) skew(0deg) translate(-285px, 0);
    -o-transform: rotate(0deg) scale(1) skew(0deg) translate(-285px, 0);
    -ms-transform: rotate(0deg) scale(1) skew(0deg) translate(-285px, 0);
    transform: rotate(0deg) scale(1) skew(0deg) translate(-285px, 0);
}
.skinner .bg-image{
    -webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(-260px, 0);
    -moz-transform: rotate(0deg) scale(1) skew(0deg) translate(-260px, 0);
    -o-transform: rotate(0deg) scale(1) skew(0deg) translate(-260px, 0);
    -ms-transform: rotate(0deg) scale(1) skew(0deg) translate(-260px, 0);
    transform: rotate(0deg) scale(1) skew(0deg) translate(-260px, 0);
}
.krycek .bg-image{
    -webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(-50px, 0);
    -moz-transform: rotate(0deg) scale(1) skew(0deg) translate(-50px, 0);
    -o-transform: rotate(0deg) scale(1) skew(0deg) translate(-50px, 0);
    -ms-transform: rotate(0deg) scale(1) skew(0deg) translate(-50px, 0);
    transform: rotate(0deg) scale(1) skew(0deg) translate(-50px, 0);
}

Now we’ll change the rules for some of the elements depending on whether the panel is collapsed or expanded. Luckily the kwicks plugin adds classes to indicate what state the panel is in.

When the class .kwicks-expanded gets added to the li of the expanding panel .opening-text opacity is set to 0 and it’s visibility is set to hidden. The same happens when the panel is collapsed to both the .opening-text and .hidden-text divs.

When the panel is expanded the .hidden-text opacity is then set to 1 and it’s visibility is then set to visible.


.kwicks-expanded .opening-text,
.kwicks-collapsed .opening-text,
.kwicks-collapsed .hidden-text {
    opacity: 0;
    visibility: hidden;
}
.kwicks-expanded .hidden-text {
    opacity: 1;
    visibility: visible;
}

The next part of the CSS sets the .bg-image back to it’s original position along the x-axis.


.kwicks-expanded .bg-image {
    -webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(0, 0);
    -moz-transform: rotate(0deg) scale(1) skew(0deg) translate(0, 0);
    -o-transform: rotate(0deg) scale(1) skew(0deg) translate(0, 0);
    -ms-transform: rotate(0deg) scale(1) skew(0deg) translate(0, 0);
    transform: rotate(0deg) scale(1) skew(0deg) translate(0, 0);
}

The last part of the CSS then changes the state of the collapsed header to visible and it’s opacity to 1.


.collapsed-header{
    opacity: 0;
    visibility: hidden;
    color: #ebe9e9;
    font-size: 60px;
    font-weight: 300;
    margin: 0;
    transform: rotate(-90deg);
    width: 450px;
    position: absolute;
    left: -161px;
    top: 161px;
    z-index: 2;
    line-height: 128px;
    text-shadow: 1px 1px 1px #000;
    transition: opacity ease-in-out 0.5s;
    transition-delay: 0.3s;
}
.kwicks-collapsed .collapsed-header {
    opacity: 1;
    visibility: visible;
}

Now we will initiate the kwicks plugin in script.js within the js folder.


$(document).ready(function() {
    $('.kwicks').kwicks({
        maxSize: '60%',
        spacing: 0,
        behavior: 'menu',
        duration: 500,
        isVertical: false,
        easing: undefined,
        autoResize: true,
        delayMouseIn: 0,
        delayMouseOut: 0,
        selectOnClick: true,
        deselectOnClick: false,
        // slideshow behavior options:
        interval: 500,
        interactive: true
    });
});

**This will work in most modern browsers but as always be sure to test before putting into real world use.

Share