Menu

Udacity: Responsive Web Design and Responsive Images

January 4, 2018 - Accessibility, CSS, HTML

Simulators, Emulators and Real Devices

In Chrome Dev Tools – Emulator icon

Pixel density

Emulate a custom device

Select Edit from the Responsive drop-down menu.
Select Add custom device.
* Device name
* Width
* Height
* Device pixel ratio: 3.5
* User agent String: Mozilla/5.0 (Linux; Android 5.0; Nexus 6 Build/XXX00x) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.59 Mobile Safari/537.36

Mobile debugging
chrome://inspect

Define the viewport

Hardware Pixlels and Device Independent Pixels
Device pixel Ratio

Calculating CSS Pixels
Hardware pixels / Device Pixel ratio = CSS Pixels

<meta name="viewport" content="width=device-width,initial-scale=1">

Relative widths

width:100%;

img, embed, object, video {
        max-width:100%;
}

Tap target sizes

48×48 px + 40px between buttons

nav a, button {
        min-width: 48px;
        min-height: 48px;
}

Media Queries

In HTML

<link rel="stylesheet" media="screen and (min-width:300px)" href="tablet.css">

In CSS

@media screen and (min-width:500px) {
    /* CSS */
}

CSS import rule – avoid

@import url("no.css") only screen and (min-width:500px);

Example

          body {
                                        background:#ff0000;
          }

      @media screen and (min-width: 401px) and (max-width: 599px) {
                        body {
                  background:#00ff00;
              }  
        }

      @media screen and (min-width: 600px) {
                body {
                                            background: #0000ff;
                             }
    }

Breakpoints

Look at the content to set breakpoints.

Small screen first
Resize the width to see where spaces are forming

<link rel="stylesheet" media="screen and (min-width:300px)" href="tablet.css">
<link rel="stylesheet" href="tablet.css">
<link rel="stylesheet" media="screen and (min-width:550px)" href="medium.css">
<link rel="stylesheet" media="screen and (min-width:700px)" href="large.css">

Grids

Flexbox

<div class="container">
    <div class="box blue"></div>
    <div class="box red"></div>
    <div class="box green"></div>
</div>



.container  {
            width:100%;
            display: flex;
            flex-wrap:wrap
}

.red {
        width:20%
        order: 2;
}

Common Responsive Patterns

Mostly Fluid

On mobile the columns are stacked, but on larger devices grid pattern starts tro appear
On largest viewport margins are added on left and right

<div class="container">
    <div class="box blue"></div>
    <div class="box red"></div>
    <div class="box green"></div>
</div>
/* mobile */
.container {
    display: flex;
    flex-wrap: wrap
}

.box {
    width: 100%
}

/* tablet */
@media screen and (min-width: 450px) {
    .blue, .green {
        width: 50%;
    }

}
/*  550px */
@media screen and (min-width: 550px) {
    .blue, .green {
        width: 50%;
    }

    .red, .violet {
        width: 33.3333333%;
    }

}
/*  Laptop */
@media screen and (min-width: 700px) {
.container {
        width: 700px;
        margin-left: auto;
        margin-right: auto;
    }

}

Layout Shifter

Most responsive pattern. Content moves around.
Use order Default order is 0.

<div class="container">
    <div class="box blue"></div>
    <div class="container" id="container2">
    <div class="box red"></div>
    <div class="box green"></div>
    </div>
        <div class="box orange"></div>
</div>

.container {
    width: 100%
    display: flex;
    flex-wrap: wrap
}

.box {
width: 100%;
}

/*  500px */
@media screen and (min-width: 500px) {
    .blue, .green {
        width: 50%;
    }

#container2 {
        width: 50%;
    }

}

/*  600px */
@media screen and (min-width: 600px) {
    .blue, .green {
        width: 25%;
        order: 1;
    }

#container2 {
        width: 50%;
    }

    .red {
    order: -1;
    widthe: 25%;
    }

}

Column Drop

.container {
    display: flex;
    flex-wrap: wrap
}

.box {
    width: 100%
}

@media screen and (min-width: 450px) {
 .dark_blue {
         width: 25%;
 }

 .light_blue {
         width: 75%;
 }
}

Off Canvas

Place less frequently used content off screen (like nav)

menu.addEventListener('click', function(e) {
  drawer.classList.toggle('open');
  e.stopPropagation();
});

html, body, main {
    height: 100%;
    width:100%;
}

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: relativel
    transform: translate(0,0);
    }

    body {
        display: flexl
        flex-fllow:row nowrap;
    }

    main {
        width: auto;
        flex-grow:1;
    }

}

Images

$0.currentSrc
window.devicePixelRatio

The images can be cached! Disable cache checkbox in DevTools.

Total bits = pixels x bits per pixel

To optimize image make it smaller and better compressed.

Use Calc

/* property: calc(expression) */
width: calc(100% - 80px);
.foo {
  --widthA: 100px;
  --widthB: calc(var(--widthA) / 2);
  --widthC: calc(var(--widthB) / 2);
  width: var(--widthC);
}

100% width

img {
            max-width: 100%
}

vh and vw

height: 100vh
width: 100vw

vmin and vmax

height: 100vmin
width: 100vmin

height: 100vmax
width: 100vmax

Relative sizing with margin


body { margin: 0; width: 100%; } img { float: left; width: calc((100% - 20px) / 3); margin: 0 10px 0 0; } img:last-of-type { margin: 0; }

srcset

Define images with pixel dnsity

<img src="default.png" 
                    srcset="photo.png 1x, photo@2x.png 2x" 
/>
<img src="lighthouse-200.jpg" sizes="50vw"
     srcset="lighthouse-100.jpg 100w, lighthouse-200.jpg 200w,
             lighthouse-400.jpg 400w, lighthouse-800.jpg 800w,
             lighthouse-1000.jpg 1000w, lighthouse-1400.jpg 1400w,
             lighthouse-1800.jpg 1800w" alt="a lighthouse">
<picture>
  <source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x">
  <source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x">
  <img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" alt="a head carved out of wood">
</picture>

Image optimization

https://github.com/BBC-News/Imager.js/

Image – background with gradients

body {
      background:
      linear-gradient(27deg, #151515 5px, transparent 5px) 0 5px,
      linear-gradient(207deg, #151515 5px, transparent 5px) 10px 0px,
      linear-gradient(27deg, #222 5px, transparent 5px) 0px 10px,
      linear-gradient(207deg, #222 5px, transparent 5px) 10px 5px,
      linear-gradient(90deg, #1b1b1b 10px, transparent 10px),
      linear-gradient(#1d1d1d 25%, #1a1a1a 25%, #1a1a1a 50%, transparent 50%, transparent 75%, #242424 75%, #242424);
      background-color: #131313;
      background-size: 20px 20px;
    }

Image with gradient background and static image

    body {
      background: url(html5.svg) no-repeat;
      background-position: 97% 95%;
      background-size: 5%;
      height: 100vh;
      margin: 0;
    }
    html {
      background: linear-gradient(#000, white) no-repeat;
      height: 100vh;
    }

Image background-size: cover;

Scales image to fit width and height without distorting it.

Image is sized so that it is as small as possible while still completely filling its container.

   body {
      align-items: center;
      background-image: url(albino_kookaburra.jpg);
      background-repeat: no-repeat;
      background-size: cover;
      display: flex;
      font-size: 10vw;
      font-family: "Roboto Condensed";
      text-shadow: 5px 5px 15px #333;
      height: 100vh;
      justify-content: center;
      margin: 0;
    }

Image background-size: contain;

The image is sized so that it is as large as possible while still being completely visible inside the container.

div.photo {
    background-size: contain;
    float: left;
    margin: 0 2vw 1vw 0;
    height: 50vw;
    position: relative;
    top: 3px;
    transition: all 0.5s;
    width: 50vw;
}

Images for different resolutions

    body {
      align-items: center;
      display: flex;
      height: 100vh;
      justify-content: center;
    }

    div {
      background-image: url(icon1x.png);
      background-image: -webkit-image-set(url(icon1x.png) 1x, url(icon2x.png) 2x);
      background-image: image-set(url(icon1x.png) 1x, url(icon2x.png) 2x);
      height: 128px;
      width: 128px;
    }

Images for different screen widths

    div {
      background-image: url(koala.jpg);
      background-size: cover;
      height: 50vw;
      transition: background-image 2s;
      width: 50vw;
    }
    @media screen and (max-width: 500px) {
      div {
        background-image: url(koala_crop.jpg);
      }
    }

Symbol Characters

There are more than 110,000 characters.
https://unicode-table.com/en/sets/

Set charset to utf-8
http-equiv defines name of a HTTP header

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

Font icons

http://fontello.com/
http://weloveiconfonts.com/

@import url(http://weloveiconfonts.com/api/?family=zocial);

[class*="zocial-"]:before {
  font-family: 'zocial', sans-serif;
    display: inline-block;
}

<li class="zocial-twitter">Twitter</li>

SVG


DataURI

<img src="data:image/svg+xml;base64,[data]">
background:url(data:image/svg+xml;base64,...data...);

srcset

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="Image" />

srcset with sizes attribute

Informs browser to know which image to download as the width is defined in CSS and not available at HTML data response.

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" sizes="50vw" alt="Image" />

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" sizes="(max-width:250px) 100vw, 50vw" alt="Image" />

<img  src="images/great_pic_800.jpg"
      sizes="(max-width: 400px) 100vw, (min-width: 401px) 50vw"
      srcset="images/great_pic_400.jpg 400w, images/great_pic_800.jpg 800w"
      alt="great picture">

Picture

Use polyfill
http://scottjehl.github.io/picturefill/

  <picture>
    <source srcset="kit.webp" type="image/webp">
    <img src="kit.jpg" alt="Two grey tabby kittens">
  </picture>
  <picture>
    <source media="(min-width:650px)" srcset="kit-large.jpg">
    <source media="(min-width:450px)" srcset="kit-small.jpg">
    <img src="kit.jpg" alt="Two grey tabby kittens">
  </picture>
<picture>
  <source
    media="(min-width: 1000px)"
    srcset="kookaburra_large_1x.jpg 1x, kookaburra_large_2x.jpg 2x">
  <source
    media="(min-width: 500px)"
    srcset="kookaburra_medium_1x.jpg 1x, kookaburra_medium_2x.jpg 2x">
  <img src="kookaburra_small.jpg"
    alt="The kookaburra: a terrestrial tree kingfisher native to Australia and New Guinea">
</picture>

Accessibility

Use alt attributes

Screen reader – Chrome extension

http://www.chromevox.com/
https://chrome.google.com/webstore/detail/chromevox/kgejglhpjiefppelpmljglcjbhoiplfn?hl=en-US

Tables

Hidden Columns

Hides columns based on importance


.longName { display: none; }

No more tables

Table is collapsed and resembles the list.
Example: https://codepen.io/JohnMav/pen/BoGJNy


<table> <thead> </thead> <tbody> <tr> <td data-th="Team"> </td> </tr> </tbody> </table>
@media screen and (max-width: 500px) {

table, thread, tbody, th, td, tr {
    display: block;
}

thread tr {
position: absolute;
top: -9999px;
left: -9999px
}

td {
position: relativel
padding-left: 50%;
}

td:before {
position: absolute;
left: 6px;
content: attr(data-th);
font-weight: bold;
}

}

Contained tables

div.contained_table {
width: 100%;
overflow-x: auto;
}
<div class="contained_table">
 <table>

 </table>
</div>

Fonts

Ideal width: 45-90 characters on line
Best 65 characters per line on the web

Base font at least 16px
Line height at lleast 1.2em

Minor breakpoint

For small changes

Sources