Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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…
<!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="&quot;Can I Use&quot; report for grids">CSS grids</a> and <a href="http://caniuse.com/#search=columns" title="&quot;Can I Use&quot; 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