A Pen by Robert Claypool on CodePen.
Created
April 3, 2019 09:39
-
-
Save 3kynox/7d9abef3b50f274c3cc62add57623f0c to your computer and use it in GitHub Desktop.
Holy Grail Dashboard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<body> | |
<header class="ui compact inverted menu"> | |
<!-- BEGIN logo & title --> | |
<div id="logo" class="borderless item"> | |
<i class="cubes icon"></i> | |
</div> | |
<div id="title" class="item hidden-sm-down">Holy Grail Dashboard</div> | |
<!-- END logo & title --> | |
<nav class="menu"> | |
<div onClick="toggleActions()" class="link item"> | |
<i class="sidebar icon"></i> | |
</div> | |
<!-- BEGIN top right menu --> | |
<div class="right menu"> | |
<div class="ui simple dropdown item top right"> | |
<span id="name" class="text">Robert Claypool</span> | |
<i class="dropdown icon"></i> | |
<div class="menu"> | |
<div class="item"> | |
<!-- BEGIN card --> | |
<div class="ui card"> | |
<div class="content"> | |
<img class="ui tiny image" src="https://semantic-ui.com/images/avatar2/small/matthew.png"> | |
</div> | |
<div class="extra content"> | |
<div class="ui left floated compact button"> | |
<i class="user icon"></i> User Profile | |
</div> | |
<div class="ui right floated compact button"> | |
<i class="sign out icon"></i> Log Out | |
</div> | |
</div> | |
</div> | |
<!-- END card --> | |
</div> | |
</div> | |
</div> | |
<div onClick="toggleSettings()" class="link item"> | |
<i class="settings icon"></i> | |
</div> | |
</div> | |
<!-- END top right menu --> | |
</nav> | |
</header> | |
<div class="wrapper"> | |
<!-- BEGIN actions-sidebar --> | |
<!-- | |
Action sidebar defaults to "open" on large enough screens. | |
JS removes this class when it is closed. | |
--> | |
<aside id="actions-sidebar" class="open"> | |
<div id="actions-sidebar-menu" class="ui fluid vertical menu"> | |
<div class="header item">Page Actions</div> | |
<div class="item"> | |
<div class="ui transparent icon input"> | |
<input type="text" placeholder="Search"> | |
<i class="search icon"></i> | |
</div> | |
</div> | |
<a class="item"> | |
Action ABC | |
<div class="ui blue label">1</div> | |
</a> | |
<a class="item"> | |
Action DEF | |
<div class="ui blue label">1</div> | |
</a> | |
<a class="item"> | |
Action GHI | |
<div class="ui label">1</div> | |
</a> | |
<a class="item"> | |
Action JKL | |
<div class="ui label">1</div> | |
</a> | |
<a class="item"> | |
Action MNO | |
<div class="ui green label">2</div> | |
</a> | |
<a class="item"> | |
Action PQR | |
<div class="ui blue label">4</div> | |
</a> | |
<a class="item"> | |
Action STU | |
<div class="ui label">11</div> | |
</a> | |
<a class="item"> | |
Action VWX | |
<div class="ui label">2</div> | |
</a> | |
<a class="item"> | |
Action YZ! | |
<div class="ui blue label">1</div> | |
</a> | |
</div> | |
</aside> | |
<!-- END actions-sidebar --> | |
<!-- BEGIN settings-sidebar --> | |
<!-- | |
Settings sidebar defaults to "closed". | |
JS removes this class when it is opened. | |
--> | |
<aside id="settings-sidebar" class="closed"> | |
<div id="settings-sidebar-menu" class="ui fluid vertical menu"> | |
<div class="header item">App Settings</div> | |
<a class="item"> | |
<div class="ui checkbox"> | |
<input type="checkbox"> | |
<label>Setting ABC</label> | |
</div> | |
</a> | |
<a class="item"> | |
<div class="ui checkbox"> | |
<input type="checkbox"> | |
<label>Setting XYZ</label> | |
</div> | |
</a> | |
</div> | |
</aside> | |
<!-- END settings-sidebar --> | |
<!-- | |
We place <main> after the sidebars so that sibling | |
CSS selectors like '#settings-sidebar + main' will work. | |
--> | |
<main> | |
<section class="ui segment"> | |
<h1 class="ui header">Main Content</h1> | |
<p>This page uses <em>Flexbox</em> for a complete, standards-based solution to the <a href="https://en.wikipedia.org/wiki/Holy_Grail_(web_design)">Holy Grail Layout</a>, see <a href="https://philipwalton.github.io/solved-by-flexbox/demos/holy-grail/">https://philipwalton.github.io/solved-by-flexbox/demos/holy-grail/</a>. | |
</p> | |
<p>Styling and UI elements are provided by <a href="https://semantic-ui.com/">Semantic UI</a>. | |
</p> | |
</section> | |
</main> | |
</div> | |
<footer class="ui inverted vertical segment"> | |
<div id="footer-message">This is the footer!</div> | |
</footer> | |
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const VISIBILITY = Object.freeze({ | |
closed: 'closed', | |
open: 'open', | |
}); | |
function toggleActions() { | |
$('#actions-sidebar').toggleClass(VISIBILITY.closed); | |
$('#actions-sidebar').toggleClass(VISIBILITY.open); | |
$('#title').toggleClass('hidden'); | |
} | |
function toggleSettings() { | |
$('#settings-sidebar').toggleClass(VISIBILITY.closed); | |
$('#settings-sidebar').toggleClass(VISIBILITY.open); | |
} | |
(function() { | |
if (window.matchMedia) { | |
// Keep this in sync: 768px should be the breakpoint we also use in CSS. | |
const mediaQueryString = '(max-width: 768px)'; | |
// Make the sizebars auto-close when the viewport is <= 768px. | |
// Restore sizebars' previous state when the viewport is > 768px. | |
function handleViewportWidth(mql) { | |
if (mql.media !== mediaQueryString) { | |
throw new Error('Unexpected media query list.'); | |
} | |
const autoClose = mql.matches; | |
if (autoClose) { | |
// Save their current state. | |
this.actionsV = $('#actions-sidebar').hasClass(VISIBILITY.open) ? | |
VISIBILITY.open : VISIBILITY.closed; | |
this.settingsV = $('#settings-sidebar').hasClass(VISIBILITY.open) ? | |
VISIBILITY.open : VISIBILITY.closed; | |
// Now close them. | |
$('#actions-sidebar').removeClass(VISIBILITY.open); | |
$('#actions-sidebar').addClass(VISIBILITY.closed); | |
$('#settings-sidebar').removeClass(VISIBILITY.open); | |
$('#settings-sidebar').addClass(VISIBILITY.closed); | |
// Add overlay rules which stack the sidebars on top of main content. | |
// Stacking is better for small screens. | |
$('#actions-sidebar').addClass('overlay'); | |
$('#settings-sidebar').addClass('overlay'); | |
} else { | |
// Is there a saved state? Restore it. | |
if (this.actionsV === VISIBILITY.closed) { | |
$('#actions-sidebar').addClass(VISIBILITY.closed); | |
$('#actions-sidebar').removeClass(VISIBILITY.open); | |
} else { | |
$('#actions-sidebar').removeClass(VISIBILITY.closed); | |
$('#actions-sidebar').addClass(VISIBILITY.open); | |
} | |
if (this.settingsV === VISIBILITY.closed) { | |
$('#settings-sidebar').addClass(VISIBILITY.closed); | |
$('#settings-sidebar').removeClass(VISIBILITY.open); | |
} else { | |
$('#settings-sidebar').removeClass(VISIBILITY.closed); | |
$('#settings-sidebar').addClass(VISIBILITY.open); | |
} | |
// Always remove the overlay/stacking rules. | |
$('#actions-sidebar').removeClass('overlay'); | |
$('#settings-sidebar').removeClass('overlay'); | |
} | |
} | |
function initSidebars() { | |
const mql = window.matchMedia(mediaQueryString); | |
handleViewportWidth(mql); | |
// Listen for changes on the document. | |
mql.addListener(handleViewportWidth); | |
} | |
// Initialize the sidebars on load. | |
window.addEventListener('DOMContentLoaded', initSidebars, false); | |
} | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdn.jsdelivr.net/semantic-ui/2.2.6/semantic.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
/* | |
Good flexbox resources: | |
https://css-tricks.com/snippets/css/a-guide-to-flexbox/ | |
https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties | |
*/ | |
display: flex; | |
/* | |
We use "column" for the header, wrapper, and footer. | |
We use "row" for children of the wrapper: sidebar, main, sidebar | |
*/ | |
flex-direction: column; | |
min-height: 100vh; | |
background-color: steelblue; | |
} | |
#logo { | |
width: 4rem; | |
} | |
#title { | |
width: 14rem; | |
} | |
/* | |
#title.hidden is specific enough to override the display | |
value of Semantic's .item class which #title also uses. | |
*/ | |
#title.hidden { | |
/* | |
.hidden is not present on page load. | |
It's added/removed by button click events. | |
*/ | |
display: none; | |
} | |
nav { | |
width: 100%; | |
} | |
div.wrapper { | |
/* The default flex-direction of "row" is what we want. */ | |
display: flex; | |
/* | |
The following "flex" directive applies to this wrapper | |
in relation to its parent (the body)... | |
1: Our wrapper should fill remaining available vertical space of the body. | |
0: Don't allow it to shrink less than its content; a scrollbar should appear if needed. | |
auto: The default value. It seems to work well. | |
*/ | |
flex: 1 0 auto; | |
} | |
main { | |
flex: 1 1 auto; | |
/* | |
Our order is: | |
1 --> actions sidebar (aside) | |
2 --> main content | |
3 --> settings sidebar (aside) | |
*/ | |
order: 2; | |
padding: 1rem; | |
} | |
#actions-sidebar { | |
/* Put this on the left */ | |
order: 1; | |
} | |
#settings-sidebar { | |
/* Put this on the right */ | |
order: 3; | |
} | |
#settings-sidebar, | |
#actions-sidebar { | |
/* | |
18rem is the width of our columns. | |
They are fixed; don't grow or shrink them. | |
*/ | |
flex: 0 0 18rem; | |
/* | |
Set the overflow hidden to compensate for | |
an ugly margin/padding 5000px hack. | |
http://stackoverflow.com/a/8451485/23566 | |
*/ | |
overflow: hidden; | |
} | |
#settings-sidebar.closed, | |
#actions-sidebar.closed { | |
display: none; | |
} | |
/* | |
Add negative margin to push main under the open sidebars. | |
This works since main is given a lower z-index. | |
*/ | |
#settings-sidebar.overlay.open ~ main { | |
margin-right: -18rem; | |
z-index: 1; | |
} | |
#actions-sidebar.overlay.open ~ main { | |
margin-left: -18rem; | |
z-index: 1; | |
} | |
#settings-sidebar.overlay, | |
#actions-sidebar.overlay { | |
z-index: 2; | |
} | |
#settings-sidebar-menu, | |
#actions-sidebar-menu { | |
/* | |
This margin/padding hack is for browsers like | |
Safari which do not properly extend the flexbox | |
item height of our sidebars using `height: 100%;` | |
http://stackoverflow.com/a/8451485/23566 | |
*/ | |
margin-bottom: -5000px; | |
/* Any large number will do */ | |
padding-bottom: 5000px; | |
} | |
#footer-message { | |
padding-left: 1rem; | |
padding-right: 1rem; | |
} | |
/* | |
It's recommended to prefix media queries with "only" if you want to hide | |
their styles from old browsers. http://stackoverflow.com/a/8595600/23566 | |
*/ | |
@media only screen and (max-width: 768px) { | |
/* | |
hidden-sm-down is a "responsive visibility utility" | |
copied in from Bootstrap 4. I don't see any | |
similar functionality provided by Semantic UI. | |
*/ | |
.hidden-sm-down { | |
display: none !important; | |
} | |
main { | |
padding: 0.5rem; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="https://cdn.jsdelivr.net/semantic-ui/2.2.6/semantic.min.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment