Last active
August 27, 2017 02:52
-
-
Save lifenstein/ce0c4b676b51b2cdf170ae91068eec8b to your computer and use it in GitHub Desktop.
CSS-only responsive grid and masonry layout without any framework. Would be great to get some cross-browser, cross-OS, cross-device test results... Notes: 1. There's a search box that is displayed only on non-MS browsers, that doesn't affect the rest, so please ignore. 2. The JS is only used for generating randomised content for testing, not nee…
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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<title>CSS Grids and columns</title> | |
<!--<link rel="icon" href="favicon.ico" />--> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<!--<link rel="stylesheet" href="style.css" />--> | |
<style> | |
.sr-only { | |
position: absolute; | |
width: 1px; | |
height: 1px; | |
padding: 0; | |
margin: -1px; | |
overflow: hidden; | |
clip: rect(0,0,0,0); | |
border: 0; | |
} | |
body { | |
margin: 0; | |
} | |
@media (min-width: 400px) { | |
.page { | |
/* IE11 and Edge */ | |
display: -ms-grid; | |
-ms-grid-columns: 2fr 3fr; | |
-ms-grid-rows: 1.2em 7em 1.8em 1fr 4em; | |
display: grid; | |
grid-template-columns: 2fr 3fr; | |
grid-template-rows: 1.2em 7em 1.8em 1fr 4em; | |
grid-template-areas: | |
"breadcrumbs breadcrumbs" | |
"header header" | |
"search content" | |
"sidebar content" | |
"footer footer" | |
; | |
} | |
} | |
@media (min-width: 600px) { | |
.page { | |
-ms-grid-columns: 15em 1fr; /* IE11 and Edge */ | |
grid-template-columns: 15em 1fr; | |
} | |
} | |
.page > * { | |
border: 1px solid lightblue; | |
padding: 15px; | |
} | |
ul.breadcrumbs { | |
/* IE11 and Edge */ | |
-ms-grid-row: 1; | |
-ms-grid-column: 1; | |
-ms-grid-column-span: 2; | |
grid-area: breadcrumbs; | |
position: fixed; | |
z-index: 1; | |
top: 0; | |
height: 1.2em; | |
width: 100%; | |
margin: 0; | |
background: white; | |
padding: 0 15px; | |
} | |
ul.breadcrumbs li, | |
footer ul.links li { | |
display: inline-block; | |
} | |
ul.breadcrumbs li::after { | |
content: '>'; | |
font-family: monospace; | |
margin-left: 0.5em; | |
} | |
ul.breadcrumbs li:last-of-type::after { | |
content: none; | |
} | |
header { | |
/* IE11 and Edge */ | |
-ms-grid-row: 2; | |
-ms-grid-column: 1; | |
-ms-grid-column-span: 2; | |
grid-area: header; | |
background: skyblue; | |
margin-top: 1.2em; | |
} | |
@media (min-width: 400px) { | |
header { | |
margin-top: 0; | |
} | |
} | |
aside.search { | |
grid-area: search; | |
padding: 0; | |
position: relative; | |
} | |
/* IE11 and Edge don't support :placeholder-shown, ruins it. */ | |
_:-ms-lang(x), aside.search { | |
display: none; | |
} | |
aside.search input { | |
width: 100%; | |
font-size: 1.1em; | |
} | |
aside.search .instructions, | |
aside.search .results, | |
aside.search input:placeholder-shown:focus ~ .results { | |
display: none; | |
} | |
aside.search input:focus:placeholder-shown + .instructions, | |
aside.search input:focus ~ .results { | |
display: block; | |
border-bottom: 1px solid lightgrey; | |
} | |
aside.search input:focus:placeholder-shown + .instructions { | |
position: relative; | |
background: white; | |
padding: 10px; | |
} | |
aside.search input:focus ~ .results { | |
position: absolute; | |
width: 100%; | |
margin: 0; | |
padding: 0.5em 0 1em 0; | |
background: lightyellow; | |
} | |
aside.search .results li { | |
list-style: none; | |
padding: 5px 15px; | |
} | |
section.content { | |
/* IE11 and Edge */ | |
-ms-grid-row: 3; | |
-ms-grid-column: 2; | |
-ms-grid-row-span: 2; | |
grid-area: content; | |
background: aliceblue; | |
} | |
section.content > * { | |
max-width: 800px; | |
margin: 0 auto; | |
width: auto; | |
} | |
#masonry { | |
column-count: 3; | |
column-width: 10em; | |
column-fill: balance; | |
column-gap: 20px; | |
} | |
#masonry h4 { | |
margin-top: 0; | |
} | |
#masonry .brick { | |
display: inline-block; | |
width: 100%; | |
} | |
#masonry .brick .inner { | |
margin-bottom: 40px; | |
border: 1px solid lightblue; | |
padding: 20px; | |
} | |
aside.sidebar { | |
/* IE11 and Edge */ | |
-ms-grid-row: 3; | |
-ms-grid-column: 1; | |
-ms-grid-row-span: 2; | |
grid-area: sidebar; | |
background: lightcyan; | |
padding-top: 0px; | |
} | |
footer { | |
/* IE11 and Edge */ | |
-ms-grid-row: 5; | |
-ms-grid-column: 1; | |
-ms-grid-column-span: 2; | |
grid-area: footer; | |
background: honeydew; | |
} | |
footer ul.links li { | |
margin-right: 2em; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="page"> | |
<ul class="breadcrumbs" role="navigation"> | |
<li>Site</li> | |
<li>Home</li> | |
</ul> | |
<header> | |
<span>Header</span> | |
<h1>CSS Grids and columns</h1> | |
</header> | |
<aside class="search"> | |
<label for="searchBox" class="sr-only">Search</label> | |
<input type="search" id="searchBox" placeholder="Click here to search" /> | |
<div class="instructions">Type something.</div> | |
<ol class="results"> | |
<li>Result 1</li> | |
<li>Result 2</li> | |
<li>Result 3</li> | |
</ol> | |
</aside> | |
<section class="content"> | |
<div>Main content</div> | |
<h2>Testing CSS Grids and columns</h2> | |
<article> | |
<h3>Instructions</h3> | |
<p>Thanks for helping to test <a href="http://caniuse.com/#search=grid" title=""Can I Use" report for grids">CSS grids</a> and <a href="http://caniuse.com/#search=columns" title=""Can I Use" report for columns">columns</a> on your devices. </p> | |
<p>Please try opening this page in all supported browser - OS combinations, and see if they work well.</p> | |
<ol> | |
<li>The main content area should appear right below the header in mobile view, followed by sidebar content and then by footer.</li> | |
<li>The sidebar and content area both have maximum widths set, and should not keep widening on larger resolutions.</li> | |
</ol> | |
</article> | |
<section class="masonry"> | |
<h3>Masonry using CSS columns</h3> | |
<p>Refreshing the page generates a random number of blocks below with random heights.</p> | |
<div id="masonry"></div> | |
</section> | |
</section> | |
<aside class="sidebar"> | |
<h2>Sidebar</h2> | |
<ul class="links"> | |
<li><a href="https://www.google.com">Google</a></li> | |
<li><a href="https://en.wikipedia.org">Wikipedia (English)</a></li> | |
</ul> | |
</aside> | |
<footer> | |
<h2 class="sr-only">Other things on this site</h2> | |
<ul class="links"> | |
<li><a href="#masonry">About this site</a></li> | |
<li><a href="#masonry">Contact Us</a></li> | |
</ul> | |
</footer> | |
</div> | |
<!--<script src="scripts.js"></script>--> | |
<script> | |
const CONTAINER_ID = "masonry"; | |
/** | |
* Generate blocks of random sizes for demo (you don't need this.) | |
* | |
* @param {number} blockCount Number of blocks to generate | |
* @param {number} minLines Minimum number of lines in a block | |
* @param {number} maxLines Maximum number of lines in a block | |
*/ | |
function generateRandomBlocks(blockCount, minLines, maxLines) { | |
for (var i = 0; i < blockCount; i++) { | |
var blockHeading = document.createElement("h4"); | |
blockHeading.innerHTML = "Block " + (i + 1); | |
var inner = document.createElement("div"); | |
inner.setAttribute("class", "inner"); | |
inner.appendChild(blockHeading); | |
for (var j = 0; j < getRandom(minLines, maxLines); j++) { | |
inner.appendChild(getDummyLine(j+1)); | |
} | |
var block = document.createElement("div"); | |
block.setAttribute("class", "brick"); | |
block.appendChild(inner); | |
document.getElementById(CONTAINER_ID).appendChild(block); | |
} | |
} | |
/** | |
* Generates a random integer between two numbers (inclusive). | |
* | |
* @param {number} min The minimum value | |
* @param {number} max The maximum value | |
* @returns {number} A number between min and max | |
*/ | |
function getRandom(min, max) { | |
return Math.ceil(Math.random() * (max - 1 - min) + min); | |
}; | |
/** | |
* Generates a paragraph element containing "Line 1", | |
* for example. | |
* | |
* @param {number} lineNum The line number to display | |
* @returns {Element|getDummyLine.dummyLine} | |
*/ | |
function getDummyLine(lineNum) { | |
var dummyLine = document.createElement('p'); | |
dummyLine.innerHTML = "Line " + lineNum; | |
return dummyLine; | |
}; | |
generateRandomBlocks(getRandom(5, 10), 5, 20); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment