I have created a very simple popup window. What I would like is when the visitor come to the website for the first time to show the popup and he will have to choose one of the two buttons in order to close the popup. Moreover, I would like to do not show the popup box when the user has visited the site before. I know that I can use localstorage for that but I do not know the technique. Please, I need someone to write me the localstorage code that I have to add in my code so that when someone visits the website for the first time to show the popup and choose one of the two buttons, and if he comes back again to do not show the popup using localstorage memory.
Thanks
HTML:
<div id="popup">
<div id="text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque minus deleniti ex consequatur, rem, mollitia modi odit? Animi odit provident architecto omnis optio est, ut natus voluptatum, inventore deleniti laboriosam.
</div>
<div id="myButtons">
<button id="button-left">Click Left</a>
<button id="button-right">Click Right</a>
</div>
</div>
CSS:
#popup {
width: 30%;
margin: 50px auto;
padding: 50px;
border: 10px solid #000;
}
#close-button {
cursor: pointer;
}
#text {
margin-top: 20px;
}
#button-left {
display: inline-block;
padding: 10px;
background: #b4b0a9;
float: left;
margin-top: 10px;
}
#button-right {
display: inline-block;
padding: 10px;
background: #b4b0a9;
float: right;
margin-top: 10px;
}
JavaScript:
var popup = document.getElementById("popup");
var close_button = document.getElementById("close-button");
var mainText = document.getElementById("text");
var button_left = document.getElementById("button-left");
var button_right = document.getElementById("button-right");
function closeBoxLeft() {
popup.style.display = "none";
}
button_left.addEventListener("click", closeBoxLeft)
function closeBoxRight() {
popup.style.display = "none";
}
button_right.addEventListener("click", closeBoxRight)
This is the general idea. Read in the popup item via localStorage.getItem(), and if it doesn't exist, show the popup and set popup via localStorage.setItem()
var ls = localStorage.getItem('popup');
if (!ls) {
document.getElementById('popup').classList.add('show');
localStorage.setItem('popup',true);
}
.popup {
display: none;
}
.show {
display: block;
}
<div id="popup" class="popup">popup</div>
Related
I tried to build this kind of FAQ question boxes in my website:
If I click on "plus" icon or text, they won't be open. Therfore I think, there may be some errors in JavScript code.
These are codes of the FAQ boxes in HTML, CSS & JavaScript:
[But they are not working well]
// Showing/hiding FAQS answers
const faqs = document.querySelectorAll('.faq');
faqs.forEach(faq => {
faq.addEventListener('click', () => {
faq.classList.toggle('open');
// Changing icon
const icon = faq.querySelector('.faq__icon i');
if (icon.className === 'uil uil-plus') {
icon.className = "uil uil-minus"
} else {
icon.className = "uil uil-plus"
}
})
})
.faq {
padding: 2rem;
display: flex;
align-items: center;
gap: 1.4rem;
height: fit-content;
background: var(--color-primary);
cursor: pointer;
}
.faq h4 {
font-size: 1rem;
line-height: 2.2;
}
.faq__icon {
align-self: flex-start;
font-size: 1.2rem;
}
.faq p {
margin-top: 0.8rem;
display: none;
}
.faq.open p {
display: block;
}
<article class="faq">
<div class="faq__icon"><i class="uil uil-plus"></i></div>
<div class="question__answer">
<h4>Lorem Ipsum ?</h4>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptates sapiente odio natus excepturi, culpa rem deleniti? Cum pariatur aut nulla a recusandae sit itaque voluptatem optio! Possimus, iure! Mollitia, voluptatum?</p>
</div>
</article>
I do not know how to do this; can you help me, please?
I want (setting - content) to be closed every time the user clicks on any part of the window except setting - content.
but not work this code: (document.querySelector('body').addEventListener('click', function(e){....})and signals an error.
How can I do this correctly?
var icon = document.getElementsByClassName("setting--icon");
var panel = document.getElementsByClassName('setting--content');
for (var i = 0; i < icon.length; i++) {
icon[i].onclick = function(){
var setClasses = !this.classList.contains('active');
setClass(icon, 'active', 'remove');
setClass(panel, 'active', 'remove');
if (setClasses) {
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("active");
}
}
}
function setClass(els, className, fnName) {
for (var i = 0; i < els.length; i++) {
els[i].classList[fnName](className);
}
}
document.querySelector('body').addEventListener('click', function(e){
if (!(event.target == 'setting--content')) { panel.classList.remove('active');
this.nextElementSibling.classList.remove("active");
}
})
.setting--icon{
border: 1px solid red;
width:20px;
height:20px;
}
.setting--content {
position: fixed;
left: 50%;
top: -150%;
width: 50%;
height:20px;
margin: 0 auto;
text-align: center;
transition: 0.3s;
min-height: 300px;
padding: 2rem;
transform: translateX(-50%);
border:1px solid green;
}
.setting--content.active {
top: 20%;
}
<form >
<div class="setting--icon">1</div>
<div class="setting--content">
<input type="text" name="address" id="address" placeholder="search …">
</div>
</form>
<div>
<div class="setting--icon">2</div>
<div class="setting--content">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Natus explicabo repellendus quos illo eaque vitae, nostrum id accusantium. Cum est fugiat animi molestiae dicta praesentium repellat ipsa iusto dolore perspiciatis? </p>
</div>
</div>
To check which element has clicked, you can use matches method on HTMLElement, in your body click handler you can use it like this:
event.target.matches('.setting--content');
In your snippet, you are toggling the .setting--content by clicking on .setting--icon, so you should check that target is not .setting--icon like this:
event.target.matches('.setting--icon');
in order to above checkings, you should also check that clicked item is not in the .setting--content, you can do it by storing the current active panel in a variable and by using of contains method, check that clicked item is part of the .setting--content or not. like this:
var icon = document.getElementsByClassName("setting--icon");
var panel = document.getElementsByClassName('setting--content');
var activePanel = null;
for (var i = 0; i < icon.length; i++) {
icon[i].onclick = function() {
var setClasses = !this.classList.contains('active');
setClass(icon, 'active', 'remove');
setClass(panel, 'active', 'remove');
if (setClasses) {
this.classList.toggle("active");
activePanel = this.nextElementSibling;
activePanel.classList.toggle("active");
}
}
}
function setClass(els, className, fnName) {
for (var i = 0; i < els.length; i++) {
els[i].classList[fnName](className);
}
}
document.querySelector('body').addEventListener('click', function(event) {
if (!event.target.matches('.setting--content') &&
!event.target.matches('.setting--icon') &&
activePanel && !activePanel.contains(event.target)) {
setClass(panel, 'active', 'remove');
setClass(icon, 'active', 'remove');
}
})
body {
min-height: 100vh;
}
.setting--icon {
border: 1px solid red;
width: 20px;
height: 20px;
}
.setting--content {
position: fixed;
left: 50%;
top: -200%;
width: 50%;
height: 20px;
margin: 0 auto;
text-align: center;
transition: 0.3s;
min-height: 300px;
padding: 2rem;
transform: translateX(-50%);
border: 1px solid green;
}
.setting--content.active {
top: 20%;
}
<form>
<div class="setting--icon">1</div>
<div class="setting--content">
<input type="text" name="address" id="address" placeholder="search …">
</div>
</form>
<div>
<div class="setting--icon">2</div>
<div class="setting--content">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Natus explicabo repellendus quos illo eaque vitae, nostrum id accusantium. Cum est fugiat animi molestiae dicta praesentium repellat ipsa iusto dolore perspiciatis? </p>
</div>
</div>
BTW, since your .setting--content has fixed display, in below example I added style body{ min-height: 100vh; } in order to prevent body collapssed. and also I changed top property on .setting--content from -150% to -200% to run snippet correctly in preview mode.
A demo of this problem is here: https://jsfiddle.net/cwxLpf7j/62/
I am currently working on a project, where I want a navbar which has a specific designed menu. This menu is such that there are several menu items and a SINGLE sub menu. When I hover over any menu item, this submenu (which is positioned absolutely) is moved beneath that menu item using JavaScript. I have completed the moving portion of the code.
However, there is a slight problem. I have used a transition on opacity of the submenu to hide (opacity:0) and show (opacity:1) it when required. So, I put event listeners on the menu items and it worked well. However, now the problem is that when I leave (mouseleave) the menu item and go into the submenu itself, the submenu disappears and I cannot do anything with the buttons/links in the submenu. Now, I cannot put event listeners on the sub menu itself, because it is present but transparent (which will trigger hover events when not wanted). I also tried to play around with "display: none" but that destroyed the beautiful transition on the opacity.
I hope you understood. I have created a small demo of what I did here: https://jsfiddle.net/cwxLpf7j/62/.
Here is the code anyways:
const listItems = document.querySelectorAll("li");
const box = document.querySelector(".box");
// This portion adds event listeners to each item in the list
// which hide or show (change opacity) of the box below.
listItems.forEach((item, index) => {
item.addEventListener("mouseenter", () => {
box.style.opacity = 1;
})
item.addEventListener("mouseleave", () => {
box.style.opacity = 0;
})
})
// If I add hover event on the box itself, it will trigger
// without actually having to hover over the list item. Also
// I tried playing with display:none to hide the box fully when
// the list is not being hovered. But that caused to destroy
// the transition on the opacity fully.
// UNCOMMENT THIS PORTION OF CODE TO SEE WHAT I DID
// box.addEventListener("mouseenter", ()=>{
// box.style.opacity = 1;
// })
// box.addEventListener("mouseleave", ()=>{
// box.style.opacity = 0;
// })
.box {
width: 300px;
background-color: black;
color: white;
padding: 20px;
opacity: 0;
transition: 0.5s;
}
ul {
list-style: none;
padding: 0;
margin: 4px;
}
li {
display: inline;
padding: 5px 15px;
background-color: lightblue;
cursor: pointer;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<div class="box">
<h1>Hello</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati impedit, ad. Accusamus tenetur vel praesentium quas vero, voluptates ipsam vitae officia, ut culpa dolor porro, officiis incidunt aspernatur nostrum facilis!</p>
</div>
This appears – at first glance – to be possible with just CSS:
.box {
width: 300px;
background-color: black;
color: white;
padding: 20px;
opacity: 0;
transition: 0.5s;
/* to ensure that hovering the sub-menu doesn't trigger the
sub-menu to reveal itself while hidden: */
pointer-events: none;
}
ul {
list-style: none;
padding: 0;
margin: 4px;
}
/* here use the :is() pseudo-class function, along with the
adjacent-sibling combinator ('+') to style the .box element
whenever the ul matches any of the pseudo-classes within
that function; we also couple this selector with the .box
class-selector to match those same states: */
ul:is(:hover, :active, :focus, :focus-within) + .box,
.box:is(:hover, :active, :focus, :focus-within) {
/* we revert the pointer-events to auto, to enable
interaction: */
pointer-events: auto;
/* and, of cousre, update the opacity as before: */
opacity: 1;
}
li {
display: inline;
padding: 5px 15px;
background-color: lightblue;
cursor: pointer;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<div class="box">
<h1>Hello</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati impedit, ad. Accusamus tenetur vel praesentium quas vero, voluptates ipsam vitae officia, ut culpa dolor porro, officiis incidunt aspernatur nostrum facilis!</p>
</div>
JS Fiddle demo.
The caveat of the above approach is that the .box element's display and interactivity is based on an interaction with the <ul> rather than its descendant <li> elements, as there is (as yet) no parent-selector in CSS.
This approach, though, can be modified using JavaScript to apply, or remove, a class-name on – or other attribute-value of – the parent <ul> as below:
document.querySelectorAll('li').forEach(
(elem) => {
elem.addEventListener('mouseenter', () => {
elem.parentNode.classList.add('isInteractive');
});
elem.addEventListener('mouseleave', () => {
elem.parentNode.classList.remove('isInteractive');
});
});
.box{
width: 300px;
background-color: black;
color: white;
padding: 20px;
opacity: 0;
transition: 0.5s;
pointer-events: none;
}
ul {
list-style: none;
padding: 0;
margin: 4px;
}
/* I added this rule purely to offer a visual demonstration of the
class-name "isInteractive" being added and removed; it's in no
way required for the demo to work: */
ul.isInteractive {
background: linear-gradient(90deg, #fff0, lime);
}
/* modified the selector, below, to style the ".box" on interaction
with the <ul> only once the "isInteractive" class is added to the
<ul>: */
ul.isInteractive + .box,
.box:is(:hover, :active, :focus, :focus-within) {
pointer-events: auto;
opacity: 1;
}
li {
display: inline;
padding: 5px 15px;
background-color: lightblue;
cursor: pointer;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<div class="box">
<h1>Hello</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati impedit, ad. Accusamus tenetur vel praesentium quas vero, voluptates ipsam vitae officia, ut culpa dolor porro, officiis incidunt aspernatur nostrum facilis!</p>
</div>
JS Fiddle demo.
One warning with the above code, specifically to do with this selector rule-set:
ul:is(:hover, :active, :focus, :focus-within) + .box,
.box:is(:hover, :active, :focus, :focus-within) { ... }
If a browser doesn't understand any of the rules, then it will discard the whose set of rules; so it may be worth typing it out – for compatibility purposes – to the older format of:
ul:hover + .box,
ul:active + .box,
ul:focus + .box,
ul:focus-within + .box,
.box:hover,
.box:active,
.box:focus,
.box:focus-within { ... }
Because the above approach didn't seem to be particularly keyboard-accessible I've added some compensation that seems to better support keyboard-navigation, though this has led to me wrapping the <li> text in an <a> tag to enable tab-navigation. This updated approach is below:
document.querySelectorAll('li').forEach(
(elem) => {
elem.addEventListener('mouseenter', () => {
elem.parentNode.classList.add('isInteractive');
});
elem.addEventListener('mouseleave', () => {
elem.parentNode.classList.remove('isInteractive');
});
});
.box {
width: 300px;
background-color: black;
color: white;
padding: 20px;
opacity: 0;
transition: 0.5s;
pointer-events: none;
}
ul {
list-style: none;
padding: 0;
margin: 4px;
}
ul:is(:hover, :active, :focus, :focus-within)+.box,
.box:is(:hover, :active, :focus, :focus-within) {
pointer-events: auto;
opacity: 1;
}
li {
display: inline;
padding: 5px 15px;
background-color: lightblue;
cursor: pointer;
}
/* this is to allow links to be less-visible within the <li>
elements, if you don't want them to dominate your theme
although it may be considered more accessible if you do
allow your users to easily identify <a> elements: */
li a {
color: inherit;
text-decoration: inherit;
font-weight: inherit;
}
/* here we style all <a> elements (modify to your aesthetic) to have
default presentation in order to allow transitions: */
a {
outline: solid transparent;
outline-offset: 0;
transition: all 0.2s ease-in-out;
}
/* we transition to these styles in order to allow some movement
to occur to draw the eye: */
a:is(:focus, :active, :hover) {
outline: solid #0cc;
outline-offset: 0.2rem;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<div class="box">
<h1>Hello</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati impedit, ad. Accusamus tenetur vel praesentium quas vero, voluptates ipsam vitae officia, ut culpa dolor porro, officiis incidunt aspernatur nostrum facilis!</p>
</div>
JS Fiddle demo.
References:
CSS:
:focus-within.
:is().
:outline.
:outline-offset.
JavaScript:
Arrow Functions.
Element.classList API.
EventTarget.addEventListener().
Node.parentNode
The simplest solution I could think of is to enclose menu and info box into a container and listen for events on that container.
const listItems = document.querySelectorAll("li");
const box = document.querySelector(".box");
const menu = document.querySelectorAll(".menu");
for(let i = 0; i < menu.length; i++)
{
menu[i].addEventListener("mouseenter", onMouseEvent, true); //event listener on all children as well
menu[i].addEventListener("mouseleave", onMouseEvent); //to make it simple we only listen on .menu box
}
function onMouseEvent(e)
{
const isMouseEnter = e.type == "mouseenter";
if (isMouseEnter && e.target.tagName != "LI")
return;
box.classList.toggle("show", isMouseEnter); //avoid using inline style
}
.box {
width: 300px;
background-color: black;
color: white;
padding: 20px;
opacity: 0;
transition: 0.5s;
display: inline-block;
}
.box.show
{
opacity: 1;
}
ul {
list-style: none;
padding: 0;
margin: 4px;
}
li {
display: inline;
padding: 5px 15px;
background-color: lightblue;
cursor: pointer;
}
.menu
{
background-color: pink;
display: inline-block;
}
<div class="menu">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<div class="box">
<h1>Hello</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Obcaecati impedit, ad. Accusamus tenetur vel praesentium quas vero, voluptates ipsam vitae officia, ut culpa dolor porro, officiis incidunt aspernatur nostrum facilis!</p>
</div>
So, this is a site that i'm currently working on and everything is fine except this:
As i got warned by one of the guys reviewing my current code, my menu/navigation disappears after being open and closed in its media-querie state, and resized back to monitor-width.
Simplified - follow these steps to see the problem:
Open the code snippet (i would suggest CodePen since the result is shown properly in it) and briefly admire my design. Tthat's it, thank you for your help. Just kidding, next step: resize the browser to the mentioned size (width 480px or less) so that you see the hamburger menu icon on top right, open the menu clicking on the icon, close it, and than change the browser back to full screen size! Do you see the navigation bar on the left?!
What am i missing here? I suppose that it should be a few more lines of JavaScript for some after state (just started learning JS so i dont know), but please look into it and teach me about possible solution(s).
And yes i know, it shouldn't affect any of those mobile users that i'm targeting with my media-queries 'cause nobody will resize it like that and barely anyone will see this, BUT...first thing - i want to make it perfect, and second - if there is something i missed or did wrong i want to hear about it and learn how to fix it/make it right.
Here is the CodePen link: https://codepen.io/anon/pen/VxmMrJ
And here is the code snippet:
function myFunction() {
var x = document.getElementById("menu");
if (x.style.display === "block") {
x.style.display = "none";
}
else {
x.style.display = "block";
}
}
#media only screen and (max-width: 480px) {
.networks, .sidenav, .image-row, .foot1, .foot3 {
display: none;
}
body {
display: block;
width: 100%;
height: 100%;
background-color: #e1e1e1;
}
.page-wrap {
display: block;
margin-top: 0px;
width: 100%;
height: 100%;
margin-left: auto;
margin-right: auto;
z-index: 0;
}
.logo {
display: inline-block;
float: left;
width: 75%;
margin-left: 2.5%;
}
.logoImg {
width: 200%;
}
.menuIcon {
display: inline-block;
float: right;
width: 10%;
margin-top: 6%;
margin-right: 5.5%;
border: none;
z-index: 3;
}
.navButton {
display: block;
width: 100%;
background-color: #e1e1e1;
border: none;
z-index: 3;
}
.navButton:focus {
outline: none;
}
#menu {
display: none;
position: relative;
width: 90%;
margin-left: 5%;
margin-right: 5%;
margin-top: 2.5%;
padding-bottom: 2.5%;
z-index: 3;
}
.main {
display: block;
width: 90%;
height: auto;
padding-bottom: 7.5%;
margin-top: 2.5%;
margin-left: 5%;
margin-right: 5%;
z-index: 1;
}
.textbox {
display: block;
width: 95%;
margin-top: 5%;
margin-left: auto;
margin-right: auto;
font-size: 1.25em;
text-align: justify;
}
.myPhoto {
display: block;
width: 50%;
margin-left: auto;
margin-right: auto;
}
.foot2 {
display: block;
width: 100%;
padding-top: 5%;
padding-bottom: 5%;
font-size: 1.25em;
color: #324B64;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width,
initial-scale=1.0">
<link rel="stylesheet" href="test.css">
<script src="myScript.js"></script>
<title>Luka Novak</title>
</head>
<body>
<div class="page-wrap">
<div class="header">
<div class="logo">
</div>
<div class="networks">
<img src="facebook-symbol.svg" class="socialnet" alt="facebook">
<img src="instagram-symbol.svg" class="socialnet" alt="instagram">
</div>
<div class="menuIcon">
<button onclick="myFunction()" class="navButton">
<img src="https://cdn3.iconfinder.com/data/icons/gray-toolbar/512/menu-512.png"
alt="menu"
class="iconImg">
</button>
</div>
</div>
<div class="sidenav col-5" id="menu">
about us
services
contact
</div>
<div class="main col-18">
<article class="textbox">
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"
</article>
<div class="image-row">
<div class="image1">
</div>
<div class="image2">
</div>
<div class="image3">
</div>
</div>
</div>
<div class="footer col-24">
<p class="foot1">Some info</p>
<p class="foot2">design by me</p>
<p class="foot3">More info</p>
</div>
</div>
</body>
</html>
It would be better to do this with a CSS class that it only changed in your mobile media query.
https://codepen.io/anon/pen/KRmYVR
CSS
#media only screen and (max-width: 480px) {
.mobileshow {
display: block !important;
}
}
JS
function myFunction() {
var x = document.getElementById("menu");
if(x.classList.contains("mobileshow")) {
x.classList.remove("mobileshow");
}
else {
x.classList.add("mobileshow");
}
}
Those attributes of "element.style" can only be set a value rather than get their value(you can run "console.log(x.style.display)" to prove it). if you must to get styles of an element, try "getComputedStyle"
Usually, I would hide an element by add a class, and show it by remove that class
const el = document.querySelector('.some-element')
function hideElement() {
if (!el.classList.contains('hidden')) {
el.classList.add('hidden')
}
}
function showElement() {
if (el.classList.contains('hidden')) {
el.classList.remove('hidden')
}
}
.hidden {
display: none;
}
/* you can try this, if you don't want that element to really disappear
.hidden {
opacity: 0;
}
*/
<div class="some-element"></div>
PS: My English is poor, hope you could understand it :)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I need to create a row, where three divs are positioned side by side:
In the divs, the middle one is always vertical aligned middle and the other ones are vertical aligned top.
I did this with the settings
Container:
display:table
Row:
display:table-row
Cell:
display:table-cell with float:none
This works fine, but now the requirement is, that only the last div should become vertical bottom aligned. (see attachment 2):
Anyways, I couldn't manage it, since display table cell and vertical-align:top on the left and right div doesn't allow me to vertical align bottom.
I also tried to use position absolute on the last div, but I can't know if the variable height of the div is bigger in the left or in the right div
thanks for your help!
flexbox can do that quite easily
* {
box-sizing: border-box;
}
.wrap {
width: 80%;
margin: 5vh auto;
border: 1px solid grey;
display: flex;
}
.col {
display: flex;
flex-direction: column;
flex: 1;
border: 1px solid green;
padding: 1em;
margin: 1em;
}
.left,
.right {
flex: 2;
/* just a number...means they are twice as wide as the middle */
}
.middle {
justify-content: center;
}
header {
flex: 0 0 25px;
background: red;
margin-bottom: 1em;
}
nav {
flex: 0 0 35px;
background: blue;
margin-bottom: 1em;
}
.content {
flex: 0 0 auto;
background: orange;
margin-bottom: 1em;
}
footer {
height: 50px;
background: green;
width: 50px;
align-self: flex-end;
width: 100%;
margin-top: auto;
}
<div class="wrap">
<div class="col left">
<header></header>
<nav></nav>
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab, impedit. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate cum magnam maiores unde consequuntur, similique deserunt delectus omnis expedita in, laborum praesentium consequatur
eius adipisci saepe rerum reprehenderit nostrum temporibus.</div>
<footer></footer>
</div>
<div class="col middle">
<div class="content">Lorem ipsum dolor sit amet.</div>
</div>
<div class="col right">
<header></header>
<nav></nav>
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus, modi!</div>
<footer></footer>
</div>
</div>
I would do this with flexbox: http://codepen.io/pjetr/pen/KpYzqj
div { display: flex; }
/* I was required to add some code, to accompany the codepen link :) */
but remember to check this: http://caniuse.com/#feat=flexbox