Scrolling to the bottom of a span automatically with javascript - javascript

I have a span defined, to which I am occasionally adding text and I am trying to get it to scroll to the bottom of the "box" but without success.
I have the span defined as:
<tr>
<td style="height:130px; border: 1px solid black;">
<div class="scrollable">
<span id="infoWindow"></span>
</div>
</td>
</tr>
With
div.scrollable
{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
And I am adding to it as follows:
document.getElementById("infoWindow").innerHTML+="Just some blurb<hr>";
var objDiv = document.getElementById("infoWindow");
I have tried two different approaches:
objDiv.scrollTop = objDiv.scrollHeight - objDiv.clientHeight;
and
objDiv.scrollTop = objDiv.scrollHeight;
But neither work. What am I doing wrong? Many thanks!

scrollHeight and clientHeight are properties which are calculated when DOM has been fully painted. You should subscribe to event DOMContentLoaded to be sure the calculations are done.
There is a function scrollIntoView which you can use on any element which does exactly the name suggests. MDN - scrollIntoView. You can also define some options for scrolling like smoothness and position where to scroll exactly on element.
Here is an example I wrote to test this.
Keep in mind that scrollIntoView triggered by code example will impact SO scroll behavior.
const paragraphs = ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliter enim nosmet ipsos nosse non possumus. Sin dicit obscurari quaedam nec apparere, quia valde parva sint, nos quoque concedimus; Quis autem de ipso sapiente aliter existimat, quin, etiam cum decreverit esse moriendum, tamen discessu a suis atque ipsa relinquenda luce moveatur? Duo Reges: constructio interrete. Quem enim ardorem studii censetis fuisse in Archimede, qui dum in pulvere quaedam describit attentius, ne patriam quidem captam esse senserit? Id quaeris, inquam, in quo, utrum respondero, verses te huc atque illuc necesse est.',
'Nec vero sum nescius esse utilitatem in historia, non modo voluptatem. Hanc in motu voluptatem -sic enim has suaves et quasi dulces voluptates appellat-interdum ita extenuat, ut M. Hunc ipsum Zenonis aiunt esse finem declarantem illud, quod a te dictum est, convenienter naturae vivere. Suo enim quisque studio maxime ducitur. Manebit ergo amicitia tam diu, quam diu sequetur utilitas, et, si utilitas amicitiam constituet, tollet eadem.',
'Partim cursu et peragratione laetantur, congregatione aliae coetum quodam modo civitatis imitantur; Hic nihil fuit, quod quaereremus. Stoici restant, ei quidem non unam aliquam aut alteram rem a nobis, sed totam ad se nostram philosophiam transtulerunt; Deinde disputat, quod cuiusque generis animantium statui deceat extremum. Tibi hoc incredibile, quod beatissimum. Sed haec ab Antiocho, familiari nostro, dicuntur multo melius et fortius, quam a Stasea dicebantur. Quid enim necesse est, tamquam meretricem in matronarum coetum, sic voluptatem in virtutum concilium adducere? Ne vitationem quidem doloris ipsam per se quisquam in rebus expetendis putavit, nisi etiam evitare posset.'
];
const container = document.getElementById('infoWindow');
const paragraphElements = paragraphs.map((paragraphText, index) => {
const newParagraph = document.createElement('p');
newParagraph.innerHTML = paragraphText;
newParagraph.style.animationDelay = `${.8 * index + 1}s`;
return newParagraph;
});
const demostrateScrolling = () => {
const scroller = document.getElementById('scroller');
const scrollerOptions = {
behavior: 'smooth',
block: "start",
inline: "nearest"
};
scroller.addEventListener('click', () => {
container.querySelector('p:last-child').scrollIntoView(scrollerOptions);
});
paragraphElements.map(p => {
container.appendChild(p);
});
}
document.addEventListener('DOMContentLoaded', demostrateScrolling);
body {
font-family: 'Tahoma';
}
#infoWindow {
height: 200px;
overflow-y: auto;
margin: 10px;
}
#infoWindow p {
padding: 10px;
margin: 10px;
background-color: navy;
color: white;
border-radius: 5px;
animation-name: FadeIn;
animation-duration: .4s;
animation-fill-mode: backwards;
}
#keyframes FadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#scroller {
width: auto;
background-color: lightblue;
border-radius: 24px;
padding: 5px;
margin: 5px;
font-size: 10px;
cursor: pointer;
}
<h2>Scroll To Bottom</h2>
<div id="infoWindow"></div>
<span id="scroller">Scroll to bottom</span>

refer this https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop
scrolling is applicable only to scrollable elements
var i= 0;
while(i<10){
document.getElementById("infoWindow").innerHTML+="Just some blurb<hr>";
i++;
}
//get the total height of your element
var bottomPosition = document.getElementById("infoWindow").offsetHeight;
//set scroll of container element
document.querySelector(".scrollable").scrollTop = bottomPosition;
div.scrollable
{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
/* height is no defined for inline-elements so make span inline-block or block*/
#infoWindow{
display:inline-block;
}
<table>
<tr>
<td style="height:130px; border: 1px solid black;">
<div class="scrollable">
<!-- added style for span element -->
<span id="infoWindow"></span>
</div>
</td>
</tr>
</table>

Related

On which element should i apply transition?

I was creating a project in which i needed to show heading for a topic and when the mouse goes over it, it changes to information of that heading. I have managed to make it work however i don't want it to change instantly, i want to apply transition on it so it makes it more pleasing. The problem is i don't know which element to put it on. I tried to put it on all three but it didn't work. I would appreciate if someone helped me with it. Here's my code:
HTML
<div class="sop-container">
<div class="sop-body" onmouseover="showSop()" onmouseout="hideSop()">
<h1 id="sop-head">Lorem Ipsum</h1>
<p class="sop-p" id="sop-p">Lorem ipsum dolor sit amet consectetur adipisicing elit. Veritatis, tempore laudantium maiores eligendi tempora ab repellat nam possimus sit molestiae cumque officiis corporis optio officia commodi consequatur aperiam quaerat odit.</p>
</div>
<div class="sop-img">
<img src="masks.jpg" alt="">
</div>
</div>
CSS
.sop-body{
flex: 1;
background-color: #EAC435;
transition: 3s ease;
}
.sop-body h1{
text-align: center;
margin-top:125px;
transition: 3s ease-in-out;
}
.sop-body p{
display: none;
margin:5%;
letter-spacing: 1px;
font-size: large;
margin-top: 80px ;
transition: 3s ease-in-out;
}
.sop-img{
flex: 1;
overflow-y: hidden;
}
Javascript (just in case)
var sopBody = document.getElementById("sop-p");
var sopHead = document.getElementById("sop-head")
function showSop(){
sopBody.style.display = "block"
sopHead.style.display = "none"
}
function hideSop(){
sopBody.style.display = "none"
sopHead.style.display = "block"
}
transition doesn't work on the display property. Just think for a moment about how could you render a partial display element. You can't.
Alternatively, you can use opacity here
var sopBody = document.getElementById("sop-p");
var sopHead = document.getElementById("sop-head")
function showSop() {
sopBody.style.opacity = "1"
sopHead.style.opacity = "0"
}
function hideSop() {
sopBody.style.opacity = "0"
sopHead.style.opacity = "1"
}
.sop-body {
flex: 1;
background-color: #EAC435;
}
.sop-body h1 {
text-align: center;
margin-top: 125px;
transition: 1s ease-in-out;
}
.sop-body p {
opacity: 0;
margin: 5%;
letter-spacing: 1px;
font-size: large;
margin-top: 80px;
transition: 1s ease-in-out;
}
.sop-img {
flex: 1;
overflow-y: hidden;
}
<div class="sop-container">
<div class="sop-body" onmouseover="showSop()" onmouseout="hideSop()">
<h1 id="sop-head">Lorem Ipsum</h1>
<p class="sop-p" id="sop-p">Lorem ipsum dolor sit amet consectetur adipisicing elit. Veritatis, tempore laudantium maiores eligendi tempora ab repellat nam possimus sit molestiae cumque officiis corporis optio officia commodi consequatur aperiam quaerat odit.</p>
</div>
<div class="sop-img">
<img src="masks.jpg" alt="">
</div>
</div>

Is it okay to store an Object on a DOM element in a vanilla JS plugin?

I'm converting jQuery plugins to Vanilla Javascript. I've adopted a Bootstrap-style plugin structure in my example. Once I've instantiated the Accordion object I save it to the dom element so I can later use various methods on the object. Is this an anti-pattern? I would really appreciate any suggestions on how to handle this if it's not correct.
const Accordion = function(element, options){
this.$element = element;
this.target = this.$element.getAttribute('href') || this.$element.dataset.target;
this.$target = document.getElementById(this.target);
this.$header = document.querySelector(`.accordion-header[data-target='${this.target}']`) || document.querySelector(`.accordion-header[href='${this.target}']`);
this.options = {...Accordion.defaults, ...options};
}
Accordion.defaults = {
closeOthers: false
}
Accordion.prototype.open = function(){
this.$header.classList.add('active');
this.$target.classList.add('active');
};
Accordion.prototype.close = function(){
this.$header.classList.remove('active');
this.$target.classList.remove('active');
};
Accordion.prototype.toggle = function(){
if(this.$target.classList.contains('active')){
this.close();
} else {
this.open();
}
};
function Plugin(options){
let accordion = this.Accordion;
if(!accordion){
accordion = new Accordion(this, options);
// Is it okay to store an object on the DOM element?
this.Accordion = accordion;
}
}
const $accordions = [...document.querySelectorAll('[data-toggle="accordion"]')];
const options = {
closeOthers: true
};
/* Call the plugin */
$accordions.forEach($acc => {
Plugin.call($acc, options);
});
$accordions.forEach($acc => {
$acc.addEventListener('click', e => {
e.target.Accordion.toggle();
e.preventDefault();
});
});
const $toggle1 = document.getElementById('toggle1');
const $toggle2 = document.getElementById('toggle2');
const $acc1 = document.getElementById('acc1');
const $acc2 = document.getElementById('acc2');
$toggle1.addEventListener('click', e =>{
$acc1.Accordion.toggle();
});
$toggle2.addEventListener('click', e =>{
$acc2.Accordion.toggle();
});
body {
max-width: 500px;
margin: 0 auto;
padding: 10px;
}
.accordion {
border: 1px solid #ccc;
border-bottom: 0;
margin-bottom: 10px;
}
.accordion-header {
display: block;
padding: 10px;
text-decoration: none;
color: #000;
border-bottom: 1px solid #ccc;
}
.accordion-header.active {
background: #eee;
}
.accordion-body {
padding: 10px;
display: none;
border-bottom: 1px solid #ccc;
}
.accordion-body.active {
display: block;
}
<div class="accordion">
<a id="acc1" href="#1" class="accordion-header" data-toggle="accordion">Header1</a>
<div id="#1" class="accordion-body">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Consequatur aliquid et ipsam cupiditate. Omnis iste quas nostrum aliquid facilis ut natus excepturi deleniti nobis in similique, ex, voluptatibus commodi dolores.
</div>
</div>
<div class="accordion">
<a id="acc2" href="#2" class="accordion-header" data-toggle="accordion">Header2</a>
<div id="#2" class="accordion-body">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Consequatur aliquid et ipsam cupiditate. Omnis iste quas nostrum aliquid facilis ut natus excepturi deleniti nobis in similique, ex, voluptatibus commodi dolores.
</div>
</div>
<button id="toggle1">
Toggle 1
</button>
<button id="toggle2">
Toggle 2
</button>
I wouldn’t worry about it. The only potential problem is name collisions (some other code also tries to assign to element.Accordion and overwrites it). You could also do it with a Map.
var accordions = new Map()
function Accordion ( element ) {
accordions.set( element, this )
}
Accordion.get = element => accordions.get( element )
...
var accordion = Accordion.get( element )

My navigation disappears when the browser is resized

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

Make it possible for a jQuery appended label to toggle a checkbox

I have a list with the following markup:
<div class="container">
<div class="element">
<input type="checkbox" id="checkbox1" class="toggler">
<label for="checkbox1">Toggle +</label>
<div class="more-info">
<p>...</p>
</div>
</div>
<div class="element">
...
</div>
</div>
The purpuse is to use pure CSS to make the toggle function, so I use this to hide/show the <div class="more-info">...</div>:
.more-info {
max-height: 0;
opacity: 0;
overflow: hidden;
transition: all .3s ease;
}
.toggler:checked ~ .more-info {
max-height: 200px;
opacity: 0;
overflow: hidden;
}
Under the container, I have a button that will get (in this case it is static) element and append to the container. And this is where I have my problem, the label in the new element won't toggle the checkbox. If I make the checkbox visible and check it directly it works.
I have also made a codepen to illustrate my problem.
Thanks in advance :)
You have two issues in your code. Firstly there's a $a() which should be just $(). You're also setting the class of the appended checkbox to chekcbox instead of checkbox. Try this:
$(document).ready(function() {
var i = 1;
$('#more').click(function(e) {
e.preventDefault();
var element, checkbox, label, moreInfo, dummyText;
i++
dummyText = $('<p />').text('Similique dis egestas aptent exercitationem sequi urna, nonummy laudantium, cillum pulvinar sociis assumenda? Minus nostra atque minima duis expedita ab irure sequi lectus natoque? Nihil. Similique dis egestas aptent exercitationem sequi urna, nonummy laudantium, cillum pulvinar sociis assumenda? Minus nostra atque minima duis expedita ab irure sequi lectus natoque? Nihil.');
checkbox = $('<input />', {
id: 'checkbox' + i,
class: 'toggler',
type: 'checkbox'
});
label = $('<label />', {
for: 'checkbox' + i,
text: 'Toggle +'
});
moreInfo = $('<div />', {
class: 'more-info',
html: dummyText
});
element = $('<div />', {
class: 'element'
}).append(checkbox, label, moreInfo);
$('.container').append(element);
})
});
body {
margin: 0;
font-family: sans-serif;
font-size: 18px;
}
.container {
display: block;
margin: 50px auto;
width: 500px;
padding: 30px;
background-color: #ededed;
}
label {
display: block;
margin-bottom: 5px;
font-size: 24px;
font-weight: 700;
cursor: pointer;
}
.toggler {
display: none;
}
.more-info {
margin-bottom: 20px;
padding-bottom: 20px;
width: 100%;
max-height: 0;
overflow: hidden;
opacity: 0;
border-bottom: solid 1px #ababab;
transition: all .3s ease;
}
.more-info>p {
margin: 0;
}
.toggler:checked~.more-info {
max-height: 200px;
opacity: 1;
}
#more {
display: block;
margin: 30px auto 0;
padding: 10px 0;
width: 120px;
text-align: center;
color: #3498db;
border: solid 2px #3498db;
border-radius: 22px;
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="container">
<div class="element">
<input id="checkbox1" class="toggler" type="checkbox">
<label for="checkbox1">Toggle +</label>
<div class="more-info">
<p>Similique dis egestas aptent exercitationem sequi urna, nonummy laudantium, cillum pulvinar sociis assumenda? Minus nostra atque minima duis expedita ab irure sequi lectus natoque? Nihil. Similique dis egestas aptent exercitationem sequi urna, nonummy
laudantium, cillum pulvinar sociis assumenda? Minus nostra atque minima duis expedita ab irure sequi lectus natoque? Nihil.</p>
</div>
</div>
</div>
Get more

Dynamic Side Nav Bar

I am a newbie.
I want to build a side navigation bar like available here and here.
As of now, I am able to build a dynamic navigation bar as shown here, though it is not a proper side navigation bar.
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$("document").ready(function(){
$(".menu-button").click(function(){
$(".side-nav-menu").toggle(100);
});
});
</script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-0">
<div>
<a class="btn btn-default menu-button transparent-btn">
<i class="fa fa-bars fa-2x"></i>
<i class=""></i>
</a>
</div>
<div class="side-nav-menu btn-group-vertical" style="display:none">
<button class="btn btn-default transparent-btn btn-lg text-left">About</button>
<button class="btn btn-default transparent-btn btn-lg text-left">Schedule</button>
<button class="btn btn-default transparent-btn btn-lg text-left">Venue</button>
<button class="btn btn-default transparent-btn btn-lg text-left">Speakers</button>
<button class="btn btn-default transparent-btn btn-lg text-left">Contacts</button>
</div>
</div>
</div>
<div>
</body>
I even checked this w3schools website to build the same, but wasn't successful, as explanation is quite difficult.
Can anybody help me out with this?
What if you try this?
.btn-group-vertical {
display: inline-block;
position: absolute;
vertical-align: middle;
z-index: 1;
}
Making the menu positioned absolutely, then adding a z-index so it stays in front.
Its called an off-canvas navigation:
The CSS is:
/* Navigation Menu - Background */
.navigation {
/* critical sizing and position styles */
width: 100%;
height: 100%;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 0;
/* non-critical appearance styles */
list-style: none;
background: #111;
}
/* Navigation Menu - List items */
.nav-item {
/* non-critical appearance styles */
width: 200px;
border-top: 1px solid #111;
border-bottom: 1px solid #000;
}
.nav-item a {
/* non-critical appearance styles */
display: block;
padding: 1em;
background: linear-gradient(135deg, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 100%);
color: white;
font-size: 1.2em;
text-decoration: none;
transition: color 0.2s, background 0.5s;
}
.nav-item a:hover {
color: #c74438;
background: linear-gradient(135deg, rgba(0,0,0,0) 0%,rgba(75,20,20,0.65) 100%);
}
/* Site Wrapper - Everything that isn't navigation */
.site-wrap {
/* Critical position and size styles */
min-height: 100%;
min-width: 100%;
background-color: white; /* Needs a background or else the nav will show through */
position: relative;
top: 0;
bottom: 100%;
left: 0;
z-index: 1;
/* non-critical apperance styles */
padding: 4em;
background-image: linear-gradient(135deg, rgb(254,255,255) 0%,rgb(221,241,249) 35%,rgb(160,216,239) 100%);
background-size: 200%;
}
/* Nav Trigger */
.nav-trigger {
/* critical styles - hide the checkbox input */
position: absolute;
clip: rect(0, 0, 0, 0);
}
label[for="nav-trigger"] {
/* critical positioning styles */
position: fixed;
left: 15px; top: 15px;
z-index: 2;
/* non-critical apperance styles */
height: 30px;
width: 30px;
cursor: pointer;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' x='0px' y='0px' width='30px' height='30px' viewBox='0 0 30 30' enable-background='new 0 0 30 30' xml:space='preserve'><rect width='30' height='6'/><rect y='24' width='30' height='6'/><rect y='12' width='30' height='6'/></svg>");
background-size: contain;
}
/* Make the Magic Happen */
.nav-trigger + label, .site-wrap {
transition: left 0.2s;
}
.nav-trigger:checked + label {
left: 215px;
}
.nav-trigger:checked ~ .site-wrap {
left: 200px;
box-shadow: 0 0 5px 5px rgba(0,0,0,0.5);
}
body {
/* Without this, the body has excess horizontal scroll when the menu is open */
overflow-x: hidden;
}
/* Additional non-critical styles */
h1, h3, p {
max-width: 600px;
margin: 0 auto 1em;
}
code {
padding: 2px;
background: #ddd;
}
/* Micro reset */
*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;}
html, body { height: 100%; width: 100%; font-family: Helvetica, Arial, sans-serif; }
The HTML to be used is:
<ul class="navigation">
<li class="nav-item">Home</li>
<li class="nav-item">Portfolio</li>
<li class="nav-item">About</li>
<li class="nav-item">Blog</li>
<li class="nav-item">Contact</li>
</ul>
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger"></label>
<div class="site-wrap">
<h1>Pure CSS Off-Screen Menu</h1>
<h3>Finally, an off-screen menu that doesn't require a bunch of Javascript to work. </h3>
<p>This concept relies on the <code>:checked</code> pseudo-selector as well as the general sibling <code>~</code> selector, so it has decent browser support.</p>
<p><strong>Browsers supported:</strong> IE9+, Firefox 3.5+, Chrome any, Safari 3.2+, Opera 9.5+</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi vero nisi eos sed qui natus, ut eius reprehenderit error nesciunt veniam aliquam nulla itaque labore obcaecati molestiae eveniet, perferendis provident amet perspiciatis expedita accusantium! Eveniet, quos voluptas et, labore natus, saepe unde est nulla sit eaque tempore debitis accusantium. Recusandae.</p>
<p>Dolorem aliquam a libero reiciendis obcaecati doloribus ipsa eos laudantium, dicta in! Odit iure ut ratione, dolorum cupiditate perferendis voluptatum sapiente, dignissimos sunt necessitatibus, reprehenderit consequatur dolorem. Aliquam veniam quaerat, pariatur deserunt reiciendis vero vitae, repellat omnis sequi dolor nesciunt. Nihil similique alias impedit, obcaecati eligendi delectus voluptatum! Ipsum, vel.</p>
<p>Sint, perspiciatis nemo aut, rerum excepturi deleniti modi quos nihil corporis eum, maiores soluta labore, consectetur eligendi nesciunt. Placeat, incidunt! Illum placeat eligendi, veritatis consectetur eum! Dolor obcaecati minima ab placeat voluptatem neque modi doloribus, magnam qui voluptate eaque in. Nulla expedita hic porro architecto facere officiis vitae numquam, dolor!</p>
<p>Perferendis quis ea incidunt ducimus nisi voluptate natus. Repellat asperiores quod rerum rem quos blanditiis enim modi, veniam voluptas a facilis! Velit cum omnis, voluptatum eum inventore! Corrupti, suscipit, neque distinctio expedita est laboriosam cum aliquid minus tempora quaerat officia possimus unde vel deleniti eaque fugit accusamus iusto dolorum natus.</p>
<p>Demo by Austin Wulf. See article.</p>
</div>
DEMO AVAILABLE ON http://codepen.io/SitePoint/pen/uIemr

Categories

Resources