(1) Responsive Web Design Fundamentals
calculating CSS pixels "Screen has a resolution of 1920x1080px and a DPR of 2. Calculate the maximum *width* of a viewport in CSS pixels when in landscape mode."
divide the number of physical pixels by the device pixel ratio 1920px TIMES 1CSSpx OVER 2hardwarepx = 960CSSpx 1920 x (1/2) = 960
how to determine breakpoints
don't choose them, but let the content be your guide consider spacing - too much space means it's a good place for a breakpoint *Note: Dev Tools allows you to see the screen size as you expand to help you determine breakpoints *Including more margins also includes a breakpoint. sometimes there are micro-breakpoints
complex media queries
e.g. @media screen and (max-width:400px) @media screen and (min-width:301px) and (max-width:600px) @media screen and (min-width:601px) @media screen and (min-width:961px)
simulators & emulators
e.g. Chrome's built-in emulator in Dev Tools (phone button icon), iOS simulator, cloud-based BrowserStack
picture element
the picture element uses media queries to select which image to use
breakpoint
the point at which a page changes its layout
how to set the resolution for responsive images in CCS
use the source set attribute on the image tag
Layout Shifter
utilizes CSS order alongside width e.g. .container { display: flex; flex-wrap: wrap; } .box { width: 100%; } @media screen and (min-width: 500px) { .dark-blue { width: 50%; } #container2 { width: 50%; } } @media screen and (min-width: 600px) { .dark-blue { width: 50%; order: 1; } #container2 { width: 50%; /* default order is 0 */ } .red { width: 25.5%; order: -1; /* negative order means it will come first */ } }
calculating DRP (the difference between hardware pixels and dips)
with 1 dip to every 2 hardware pixels, the device pixel ratio (DPR) is 2
(basic) media queries
-selectively apply CSS to a specific device -a basic media query applies one characteristic as opposed to a complex media query *Media queries can be used to change the entire layout of the page design.
calculating Viewport Width "Tablet, 1024px wide, DPR1"
1024px
calculating Viewport Width "Phablet, 768px wide, DPR2.5"
307.2px *Around 300 is fine
calculating Viewport Width "Phone, 640px wide, DPR2"
640/2 = 320px
calculating Viewport Width "Laptop browser, 800px wide, DPR1"
800px
setting the Viewport
<meta name="viewport" content="width=device-width, initial-scale=1"> width=device-width matches screen's width in dips initial-scale=1 instructs browsers to establish a one-to-one relationships with dips to CSS pixels (why? b/c allows content to flow in landscape mode)
example of hamburger menu code for mobile
@media screen and (max-width: 549px) { .header__logo { height: 48px; margin-right: 0.5em; } .header__title { margin-left: 0; font-size: 2em; vertical-align: bottom; } .nav { z-index: 10; background-color: #fff; width: 300px; position: absolute; /* This trasform moves the drawer off canvas. */ -webkit-transform: translate(-300px, 0); transform: translate(-300px, 0); /* Optionally, we animate the drawer. */ transition: transform 0.3s ease; } .nav.open { -webkit-transform: translate(0, 0); transform: translate(0, 0); } .nav__item { display: list-item; border-bottom: 1px solid #E0E0E0; width: 100%; text-align: left; } .header__menu { display: inline-block; position: absolute; right: 0; padding: 1em; } .header__menu svg { width: 32px; fill: #E0E0E0; } }
setting margin in a fluid layout
@media screen and (min-width: 800px) { .container { width:800px; margin-left:auto; margin-right:auto; } }
DIPs (or dips or dps)
Device Independent Pixels A DIP is a unit of measure that relates pixels to real distance. It takes up the same amount on a display regardless of the density of device display.
prevent horizontal scrolling
set a CSS max-width:100%; so that the content (like an image) fits to the div or container *Recommends using a catch-all img, embed, object video { max-width:100%; } *Note: max-width overrides a fixed width
Mostly Fluid
similar to Column Drop where percentages are set for widths; at its largest, margins are added e.g. .container { display: flex; flex-wrap: wrap; } .box { width: 100%; } @media screen and (min-width: 450px) { .light-blue, .green { width: 50%; } } @media screen and (min-width: 550px) { .dark-blue, .light-blue { width: 50%; } .red, .green, .orange { width: 33.33333333%; } } @media screen and (min-width: 700px) { .container { width: 700px; margin-left: auto; margin-right: auto; } }
Column Drop
standard layout, columns to rows when mobile to laptop e.g. .container { display: flex; flex-wrap: wrap; } .box { width: 100%; } @media screen and (min-width: 450px) { .dark-blue { width: 25%; } .light-blue { width: 75%; } } @media screen and (min-width: 550px) { .dark-blue { width: 25%; } .light-blue { width: 50%; } }
mobile first
start small when designing *performance and content is prioritized this way*
font boosting
the browser tries to pick the primary content on the page and scales it up (not ideal)
ideal measure (responsive font)
the ideal length of a line of text between 45-90 cpl (characters per line) The ideal measure is about 65 cpl for the web. *Use measures when selecting your breakpoints. Make sure font is readable. 16px, line height 1.2em.
responsive tables - 3 ways to approach them
Hidden Columns No More Tables Contained Tables
Is this responsive? <img class="logo"> .logo { width: 125px; }
Because it's small and fixes on every device, yes. It's "responsive."
adding a media queries separate style sheet to your main HTML
Example: <link rel="stylesheet" media="screen and (min-width=500px)" href="over500px.css"> Only need to use 'screen' and 'print' for the media type *Using this means smaller files but many http requests
adding an embedded media query
Example: @media screen and (min-width=500px) { body { background-color: green } } Avoid using @import Example: @ import url("no.css") only screen and (min-width=500px); *Using this means larger files but less http requests
Additional things to keep in mind
For mobile - get rid of images for more text space and put them in when on larger devices - get rid of table columns, keeping the most important ones for mobile For all devices Make sure images are flex and responsive. For more, see "Responsive Images" Course notes.
adding an ellipsis to end of a text line e.g. This is ends in an ellipsis...
For single lines: .ellipsis { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } For multiple lines: .block-ellipsis { display: block; display: -webkit-box; max-width: 100%; height: 43px; margin: 0 auto; font-size: 14px; line-height: 1; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; }
Common Responsive Patterns
Mostly Fluid Column Drop Layout Shifter Off Canvas
Problem: the same website look different on on screens with identical resolutions
Possible solutions: (1) device pixel ratios differs between devices, (2) the viewport wasn't set
adjust CSS to make sure all touch targets are easy to hit
Search for a tags and add padding:1.5em; or padding: 1.5em inherit; To check this, go to Dev Tools, inspect the element and look at the full a tag box with padding to view the size (e.g. 50x68px)
adjust CSS to make relative widths
Search for containers and make sure that they are not fixed widths (width: 770px;) but relative widths (width: 100%;). This way, it stretches across any viewport width.
What does "thinking responsively" mean?
Thinking about the user experience for every device.
viewport
defines the area of the screen that the browser can render content to *Note: not all displays have the same pixel density (i.e. your device and your viewport)
remote debugging
View debugging on the your mobile device direclty. e.g. Chrome Canary for android, Cromium Dev channel on Linux, iOS WebKit Debug Proxy with Safari or Safari Dev Tools
DRP
device pixel ratio
hardware pixels
device pixels listed in tech specs for a device
Flex item in CSS *!!*
change the order of elements by using the CSS order attribute e.g. under a media query .red { order: 2; } .blue {order: 1; } e.g. header { width:100%; order:1; } .red { width:80%; order:2; } .blue { width:20%; order:3; } footer { width:100%; order:4; } >>> header { width:100%; order:4; } .red { width:40%; order:1; } .blue { width:60%; order:2; } footer { width:100%; order:3; } *Using this means that content can be arranged in an entirely different order on one layout from another.
grid fluid system (grids)
columns wrap to next line at the grid gets smaller e.g. Bootstrap, 960 grid
responsive images - resolution
resolution for different devices (standard v. 2x for retina)
Flexbox containers in CSS *!!*
a tool for layouts https://css-tricks.com/snippets/css/a-guide-to-flexbox/ *In CSS, display:flex; > By default, flex items fit on the same line. They won't wrap the browser will size/scale them to fit the viewport. *In CSS, flexwrap:wrap; > This will allow flex items to wrap to the next line. Instead of resizing, items are wrapped.
tap targets
anything you touch, tap, click or try to do input on
When are max-width rules applied?
anytime the viewport width is less than the valued specified, the changes will be seen (max-width: 500px) An example: body { background-color:green; } @media screen and (max-width: 400px) { body { background-color:red; } } @media screen and (min-width: 600px) { body { background-color:blue; } }
Why use relative positions rather than absolute positions (e.g. width=100% or width=350px) in CSS
b/c the content (like an image) will be fixed at its width and overflow the screen making the user have to scroll horizontally **Note a conflict in lesson, is width=100% always responsive if contained?**
tap target sizes
big enough and spaced enough 48 x 48 px 40 x 40 px with spacing e.g. nav a, button { min-height: 40px; min-width: 40px; } *Use min- because we don't want it to be smaller than this.
"Hidden Columns" responsive table method
hides columns that are less important as the viewport size gets smaller *Caution: You are basically hiding content from the user. Try using abbr. data instead. e.g. @media screen and (max-width: 499px) { .gamescores { display:none; } }
how to set the viewport properly
instead of using the hardware pixels, the browser reports the number in DIPs
minor breakpoints
major breakpoints = margins and padding minor breakpoints = font weight, font size (can change the display view to make size larger)
most common media queries used
min-width and max-width *Avoid using min-device-width because this based on the size of the screen (not the browser)
responsive images - cropped images (art direction)
picture element *See picture element notecard
Off Canvas
places less common containers off screen (like menus and navigation) *Like a hamburger icon page* utilizes the CSS transform and transition e.g. nav { width: 300px; height: 100%; position: absolute; transform: translate (-300px, 0); transition: transform 0.3s ease; } nav.open { transform: translate (0, 0); } @media screen and (min-width: 600px) { nav { position: relative; tranform: translate (0, 0); } body { display: flex; flex-flow: row nowrap; } main { width: auto; flex-grow: 1; } } *(with javascript???)* menu.addEventListener('click', function(e) { drawer.classList.toggle('open'); e.stopPropagation(); });
"No More Tables" responsive table method
with a smaller viewport, the table displays the data like a long list as opposed to table data essentially removing it from the table or having it not act like a table anymore e.g. @media screen and (max-width:500px) { table, thead, tbody, th, tr,td { display: block; } /*removes table header from view, positioning it way off screen so that accessibility readers can still "see" it */ thead, tr { position: absolute; top: -9999px; left: -9999px; } /* add padding and set the position */ td { position: relative; padding-left: 50%; } /* add row labels using the before pseudo selector */ td:before { position:absolute; left: 6px; content: attr(data-th); /* pulls values from the data-th which is used as a label for each of the rows*/ font-weight: bold; } }
"Contained Table" responsive table method
wrap the table in a div with a class <div class="contained_table"> in CSS, set the width and overflow attributes div.contained_table { width: 100%; overflow-x: auto; } The table will take up the same width but will scroll in the viewport.
