Skip to content

Instantly share code, notes, and snippets.

@dianaow
Last active March 26, 2019 13:26
Show Gist options
  • Save dianaow/d092faa0d385e53a023cfd59474bcdf6 to your computer and use it in GitHub Desktop.
Save dianaow/d092faa0d385e53a023cfd59474bcdf6 to your computer and use it in GitHub Desktop.
Visual story responsive design template
license: mit

Import CSS media query concepts:

	@media screen and (max-width:632px)

max-width refers to the width of the viewport. For a device with a screen or window with max-width of 632px, apply the style. When you change the size of the browser on your desktop, the CSS will change to different media query setting and you might be shown with the styling for mobiles.

	@media screen and (max-device-width:632px)

max-device-width refers to the viewport size of the device regardless of orientation, current scale or resizing. When you change the size of the browser window on your desktop, the CSS style won't change to different media query setting.

In Javascript:

	screen.width

Width of the viewport on page load. If your resize the browser, this value remains static.

	document.documentElement.clientWidth

Width of your element. If your resize the browser, this value changes dynamically.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport">
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css?family=Merriweather" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<script src="https://d3js.org/d3.v4.min.js" type="text/javascript"></script>
<style>
.row {
height: 100vh;
margin-top: 30px;
}
body {
font-family: 'Roboto', sans-serif;
}
h1, h3 {
font-family: 'Merriweather', serif;
padding-top: 20px;
padding-bottom: 20px;
}
.legend {
float: left;
}
.legend > p {
font-size: 0.8em;
padding-bottom: 0px;
padding-top: 20px;
padding-left: 40px;
margin-bottom: 0px;
}
#chart1, #chart2 {
position: absolute;
margin-top: 70px;
}
.view2-mobile {display: none;}
.view2-desktop {display: block;}
.chart-desc-mobile {display: none;}
.chart-desc-desktop {display: block;}
.chart-desc-desktop-wrapper {display: block;}
.chart2-wrapper{display: block;}
/* if mobile device max width 420px */
@media screen and (max-device-width: 420px) {
.container { padding: 0px; }
.view2-mobile{display: block; height: 40vh;}
.view2-desktop{display: none;}
.chart-desc-mobile{display: block;}
.chart-desc-desktop{display: none;}
.chart-desc-desktop-wrapper{display: none;}
.chart2-wrapper{display: none;}
.chart-desc-mobile-wrapper {height: 60vh;}
#chart1, #chart2 { margin-top: 90px; }
}
/* if device (iPad/iPad pro) width greater than 768px and less than 1024px */
@media screen
and (min-device-width : 768px)
and (max-device-width : 1024px) {
.container { max-width: 768px;}
.view2-mobile{display: block; height: 38vh;}
.view2-desktop{display: none;}
.chart-desc-mobile{display: block;}
.chart-desc-desktop{display: none;}
.chart-desc-desktop-wrapper{display: none;}
.chart2-wrapper{display: none;}
.chart-desc-mobile-wrapper {height: 62vh;}
.row {
margin-top: 30px;
height: 100vh;
margin-left: -80px;
}
.col-lg-8 {
flex: 0 0 100%;
max-width:100%;
}
}
</style>
</head>
<body>
<div class ='container'>
<div class='row'>
<div class='col-12 col-lg-4 chart-desc-desktop-wrapper'>
<div class ='chart-desc-desktop'>
<h1>How to build a Responsive Design Template</h1>
<p>Responsive design sure is a hassle but a necessity. Here is a template i have put together, after much trial-and-error to make charts appear aesthetically not just on desktop screens with varying widths, but also on various mobile device models.</p>
<p style="font-size:0.75em">Chart 1 is a square diagram. To maximise its space, when screen width is less than a certain breakpoint (eg. 1024px) the header and chart has their own separate columns. If Chart 2 is not too visually heavy or can been squeezed without compromising its aesthetic, then combine with Chart 1 on same screen when viewed on mobile.</p>
</div>
</div>
<div class='col-12 col-lg-8 chart-desc-mobile-wrapper'>
<div class ='chart-desc-mobile'>
<h1>How to build a Responsive Design Template</h1>
<p>Responsive design sure is a hassle but a necessity. Here is a template i have put together, after much trial-and-error to make charts appear aesthetically not just on desktop screens with varying widths, but also on various mobile device models.</p>
<p style="font-size:0.75em">Chart 1 is a square diagram. To maximise its space, when screen width is less than a certain breakpoint (eg. 1024px) the header and chart has their own separate columns. If Chart 2 is not too visually heavy or can been squeezed without compromising its aesthetic, then combine with Chart 1 on same screen when viewed on mobile.</p>
</div>
<div id="chart"></div>
</div>
<div class='view2-mobile'>
<h3 style="float:left">Header of Chart 2</h3>
<div class='legend'>
<p>Legend</p>
<div id="chart_legend"></div>
</div>
<div id="chart2"></div>
</div>
</div>
<div class='row chart2-wrapper'>
<div class='view2-desktop'>
<h3 style="float:left">Header of Chart 2</h3>
<div class='legend'>
<p>Legend</p>
<div id="chart_legend"></div>
</div>
<div id="chart2"></div>
</div>
</div>
<div class='row'>
<h3>Header of Chart 3</h3>
<div id="chart1"></div>
</div>
</div>
<script src="template2.js"></script>
<script type="text/javascript">
window.onbeforeunload = function(){ window.scrollTo(0,0); }
</script>
</body>
</html>
if(screen.width <= 1024){
var graph = d3.select('.view2-mobile')
} else {
var graph = d3.select('.view2-desktop')
}
var margin = {top: 20, right: 20, bottom: 20, left: 20}
// CREATE DOM ELEMENTS
var svg = d3.select("#chart").append("svg")
var svg1 = d3.select("#chart1").append("svg")
var svg2 = graph.select("#chart2").append("svg")
// CREATE LEGEND //
var legendX = 40
var legendY = 0
var R = (screen.width < 420 ? 10 : 6) // responsive design
var category = [{color:'navy', label:"1"},
{color:'gold', label:"2"},
{color:'DarkOrange', label:"3"},
{color:'red', label:">3"}]
var svgLegend = graph.select("#chart_legend").append("svg")
.attr("width", 260)
.attr("height", 50)
.append("g")
.attr('class', 'gLegend')
.attr("transform", "translate(" + 50 + "," + 10 + ")");
var legend = svgLegend.selectAll('.legend')
.data(category)
.enter().append('g')
.attr("class", "legend")
.attr("transform", function (d, i) {return "translate(" + i * legendX + "," + i * legendY + ")"})
legend.append("circle")
.attr("class", "legend-node")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", R)
.style("fill", d=>d.color)
legend.append("text")
.attr("class", "legend-text")
.attr("x", R*2)
.attr("y", R/2)
.style("fill", "#A9A9A9")
.style("font-size", 12)
.text(d=>d.label)
function draw() {
var width = screen.width < 420 ? 700 : ((screen.width >= 768 & screen.width <= 1024) ? 500 : (document.documentElement.clientWidth.toString() > 992 ? 620 : 500)) - margin.left - margin.right // responsive design
var height = screen.width < 420 ? 700 : ((screen.width >= 768 & screen.width <= 1024) ? 500 : (document.documentElement.clientWidth.toString() > 992 ? 620 : 500)) - margin.top - margin.bottom // responsive design
var screenWidth = screen.width > 1600 ? 1250 : Math.max(document.documentElement.clientWidth) * 0.85 // responsive design
var screenHeight = screen.width > 1600 ? 800 : Math.max(document.documentElement.clientHeight) * 0.85 // responsive design
var width1 = screenWidth - margin.left - margin.right
var height1 = screenHeight - margin.top - margin.bottom
var width2 = (screen.width <= 1024 ? width1 : width1)
var height2 = (screen.width <= 1024 ? height1*0.75*0.4 : height1*0.75)
svg.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
svg.append('rect')
.attr("width", "100%")
.attr("height", "100%")
.attr('fill', 'navy')
svg.append('text')
.attr("x", 10)
.attr("y", 30)
.style("fill", "white")
.style("font-size", 20)
.text("Viewport width: " + document.documentElement.clientWidth.toString())
svg.append('text')
.attr("x", 10)
.attr("y", 60)
.style("fill", "white")
.style("font-size", 20)
.text("SVG box width: " + width.toString())
svg.append('text')
.attr("x", 10)
.attr("y", 90)
.style("fill", "white")
.style("font-size", 20)
.text("Mobile screen width: " + screen.width.toString())
svg1.attr("width", width1 + margin.left + margin.right)
.attr("height", height1 + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg1.append('rect')
.attr("width", "100%")
.attr("height", "100%")
.attr('fill', 'gold')
svg2.attr("width", width2 + margin.left + margin.right)
.attr("height", height2 + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg2.append('rect')
.attr("width", "100%")
.attr("height", "100%")
.attr('fill', 'red')
}
window.addEventListener("resize", draw)
draw()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment