n00b pro

05. CSS responsive

Youtube: totaaldemo ‐ responsive

Deze video maakt deel uit van een HTML + CSS totaaldemo uit de Basic Web Development playlist, die begint met de video BWD 01. HTML - deel 8: praktijkdemo

https://www.youtube.com/watch?v=ruw_w5PB4Rc

Definitie

Responsive design is gericht op het bieden van een optimale gebruikservaring over een breed gamma aan schermresoluties en toestellen met één enkele code.

De site moet zich dus optimaal aanpassen ('respond') aan elke schermbreedte. Je kan in de browser inspector verschillende toestellen testen met de device toggle:

desktop
tablet
mobiel

→ het is dus één site, één code die er op alle toestellen geven goed moet uitzien

Content choreografie

Bij smaller wordende schermen zullen elementen (teksten, afbeeldingen, kaders, kolommen...) moeten herschalen / verspringen / verdwijnen. Dit noemt men de content choreografie:

Er zijn geen echte regels over wat precies wanneer moet gebeuren; dit is geheel aan jou. Probeer bredere / smallere schermen, en kijk wat goed voelt.

Responsive in 3 stappen

Stap 1: viewport metatag

Laat je mobiel toestel weten dat de site responsive is, zoniet zal het proberen de desktopversie van de site te herschalen en persen in het kleine scherm. Het is niet meer dan één viewport metatag toevoegen aan je HTML:

<head>
   ...
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   ...
</head>

Irritant genoeg kom je soms ook deze versie tegen, maar die laat de gebruiker niet inzoomen:

<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">

Stap 2: flexibele layout

2A: gebruik flexbox

Gebruik voor layout zoveel mogelijk flexbox, zeker geen positionering, bv.:

header #logo {
   position: absolute;
   top: 20px;
   left: 10px;
}

header #login {
   position: absolute;
   top: 20px;
   right: 10px;
}
header {
   align-items: flex-start;
   display: flex;
   justify-content: space-between;
   padding: 20px 10px;
}





→ zou normaal gezien al ok moeten zijn

2B: flexibele wrapper

Stel flexibele min-width en max-width in op wrappers in plaats van vaste width:

.wrapper {
   width: 960px;
}

.wrapper {
   max-width: 960px;
   min-width: 320px;
}

2C: flexibele kolommen

Gebruik geen vaste width: ...px kolombreedtes, maar flex:

.leftcol {
   width: 640px;
}
.rightcol {
   width: 280px;
}
.leftcol {
   flex: 1 1 640px; 
}
.rightcol {
   flex: 0 0 280px;
}

2D: flexibele hoogtes

Elementen moeten zich verticaal in hoogte kunnen aanpassen naargelang de herschikking van de content. Verwijder daarom height van verticaal flexibele elementen, bv. de header:

header {
   height: 250px; /* geen vaste hoogte */
}

2E: flexible blokken

Stel voor afbeeldingen en andere flexibele blokken met een maximum breedte de width en max-width properties in:

main img {
   max-width: 100%; /* mag nooit breder dan de parent zijn */
   width: 450px; /* natuurlijke breedte */
}

Stap 3: media queries

3A: bepaal breekpunt

Een breekpunt is de browserbreedte vanaf waar veranderingen aan de CSS nodig zijn. Een breekpunt bepalen is makkelijk:

Er zijn geen 'aanbevolen' breekpunten; kies wat past bij je design.

2B: voeg media query toe

Stel dat je een overgang wil op 800px, dan komt er onderaan je CSS dit blok bij:

/* CSS voor smalste schermen *
...

/* ===============
Media queries
=============== */

@media (min-width: 800px) { /* deze CSS wordt uitgevoerd vanaf 800px */

}

2C: responsive CSS

Voeg nu CSS toe aan de media query en pas eventueel andere CSS aan. Wil je bijvoorbeeld een groter lettertype en wat meer ondermarge voor <h2> vanaf 800px?

/* standaardinstelling */
h2 {
   font-size: 16px;
   margin: 10px 0;
}

/* vanaf 800px */
@media (min-width: 800px) { 
   h2 {
      font-size: 20px; /* iets groter lettertype */
      margin-bottom: 15px; /* wat meer ondermarge */
   }
}

→ meer dan dat is het niet! het is even wennen, maar daarna gaat het vanzelf

2D: meer breekpunten

Controleer je resultaat, en voeg eventueel meer breekpunten toe, van klein naar groot:

/* CSS voor smalste schermen */
...

/* ===============
  Media queries
  =============== */

/* vanaf 600px */
@media (min-width: 600px) { 
   ...
}

/* vanaf 800px */
@media (min-width: 800px) { 
   ...
}

/* vanaf 1000px */
@media (min-width: 1000px) { 
   ...
}

Stap voor stap demo

Gewenst resultaat

We willen deze pagina responsive maken:

desktop
tablet
gsm

Stap 1: viewport meta

De HTML code, mét viewport metatag in de <head>, en de niet-flexibele, niet-responsive CSS code:

<!DOCTYPE html>
<html lang="en">
<head>
   <title>Classical Page Layout</title>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <link rel="stylesheet" href="css/styles.css">
</head>
<body>
   <div id="wrapper">
      <header>
         <h1><a href="#">My Blog</a></h1>
         <p class="header_login">You are not logged in – <a href="#">login</a></p>
      </header>
      <nav id="mainmenu">
         <ul>
            <li><a href="#">home</a></li>
            <li><a href="#">link1</a></li>
            <li><a href="#">link2</a></li>
         </ul>
      </nav>
      <main>
         <nav id="leftmenu">
            <h3>Submenu</h3>
            <ul>
               <li><a href="#">item1</a></li>
               <li><a href="#">item2</a></li>
               <li><a href="#">item3</a></li>
               <li><a href="#">item4</a></li>
               <li><a href="#">item5</a></li>
               <li><a href="#">item6</a></li>
            </ul>
         </nav>
         <section id="content">
            <h3>Lorem Ipsum</h3>
            <aside>
               <section>
                  <p>
                     For further reading, see also this
                     <a href="#">more detailed article</a>
                  </p>
               </section>
               <article class="ad">
                  <h1>Advertisement</h1>
                  <p>Buy our <a href="#">brand new T-shirt</a> today!</p>
                  <img src="img/shirt.png" alt="shirt" class="article_visual">
                  <p>© <a href="#">someCompany</a></p>
               </article>
            </aside>
            <p class="content_header">Posted on 2018-11-03 by Bobby Peru</p>
            <h4>Part 1</h4>
            <p>
               But I must explain to you how all this mistaken idea of denouncing pleasure
               and praising pain was born and I will give you a complete account of the
               system, and expound the actual teachings of the great explorer of the truth,
               the master-builder of human happiness. No one rejects, dislikes, or avoids
               pleasure itself, because it is pleasure, but because those who do not know.
            </p>
            <h4>Part 2</h4>
            <p>
               Nor again is there anyone who loves or pursues or desires to obtain pain of
               itself, because it is pain, but because occasionally circumstances occur in
               which toil and pain can procure him some great pleasure. To take a trivial
               example, which of us ever undertakes laborious physical exercise, except to
               obtain some advantage from it? But who has any right to find fault with a
               man who chooses to enjoy a pleasure that has no annoying consequences, or
               one who avoids a pain that produces no resultant pleasure?
            </p>
            <p><img src="img/picture.jpg" alt="just some picture" class="content_picture"></p>
            <h4>Part 3</h4>
            <p>
               On the other hand, we denounce with righteous indignation and dislike men who
               are so beguiled and demoralized by the charms of pleasure of the moment, so
               blinded by desire, that they cannot foresee the pain and trouble that are
               bound to ensue; and equal blame belongs to those who fail in their duty
               through weakness of will, which is the same as saying through shrinking from
               toil and pain.
            </p>
            <section id="comments">
               <h4>Comments</h4>
               <article class="comment">
                  <h5 class="comment_title">
                     I love Lorem Ipsum <span class="comment_author">
                     — Alice, 3 hours ago</span>
                  </h5>
                  <p>
                     “I personally believe Lorem Ipsum is the most sensitive poem ever
                     written”. As it so contrasted oh estimating instrument. Size like
                     body some one had. Are conduct viewing boy minutes warrant expense.
                  </p>
               </article>
               <article class="comment">
                  <h5 class="comment_title"
                     >Lorem Ipsum Sucks <span class="comment_author">
                     — Bob, 2 hours ago</span>
                  </h5>
                  <p>“Tolerably behaviour may admitting daughters offending her ask own.
                  Praise effect wishes change way and any wanted. There, I said it!”</p>
               </article>
            </section>
         </section>
      </main>
      <footer>
         <p>© Rogier van der Linde, 2010</p>
         <ul>
            <li><a href="#">disclaimer</a>
            <li><a href="#">sitemap</a>
            <li><a href="#">contact</a>
         </ul>
      </footer>
   </div>
</body>
</html>
/**
 *
 * Styles
 * @author Rogier van der Linde
 *
**/
  
  
/* Reset
/* ============== */

* {
   box-sizing: border-box; /* corrigeer het box model */
   margin: 0; /* wis verschillen tussen browsers uit */
   padding: 0; /* wis verschillen tussen browsers uit */
}

img {
   border: 0;
}

/* General
/* ============== */

body {
   background-color: #999;
   font-family: Verdana;
   font-size: 16px;
}
h2, h3, h4, h5 {
   margin: 1em 0;
}
h3 {
   font-size: 16px;
   font-weight: normal;
}
h4 {
   font-size: 14px;
}
h5 {
   font-size: 12px;
   font-weight: normal;
}

/* site wrapper */
#wrapper {
   width: 900px;
   margin: 0 auto;
   background-color: white;
}


/* Header
/* ============== */

header {
   align-items: flex-start;
   background-color: #333;
   color: #ccc;
   display: flex;
   flex-flow: row nowrap;
   justify-content: space-between;
   height: 100px;
   padding: 20px;
   position: relative;
}
header h1 a {
   font-weight: normal;
   text-decoration: none;
}
header a {
   color: #ddd;
}
.header_login {
   text-align: right;
}
.header_login a:hover {
   color: white;
}


/* Menu
/* ============== */

/* top menu */
nav {
   background-color: #666;
   padding: 10px 20px;
}
#mainmenu {
   display: block;
}
#mainmenu li {
   display: inline-block;
}
#mainmenu a {
   color: #ccc;
   display: inline-block;
   height: 28px;
   line-height: 24px;
   padding: 2px 5px;
   text-align: center;
   width: 50px;
}
#mainmenu li + li:before {
   color: #999;
   content: '|';
}


/* Main
/* ============== */

main {
   display: flex;
   flex-flow: row nowrap;
}

/* sub menu */
#leftmenu {
   background-color: #FEFF99;
   padding: 10px 20px;
   width: 190px;
}
#leftmenu ul {
   list-style: none;
}

/* content */
#content {
   padding: 10px 20px;
   width: 710px;
}
.content_header {
   font-size: smaller;
   font-style: italic;
   margin-bottom: 15px;
   margin-top: 25px;
}
.content_picture {
   margin: 20px 0;
   width: 450px;
}

/* aside */
main aside {
   border: 1px solid gray;
   float: right;
   font-size: smaller;
   margin: 15px 0 10px 10px;
   padding: 10px;
   width: 160px;
}
main aside article {
   font-size: 12px;
   margin-top: 10px;
   text-align: justify;
}
.article_visual {
   display: block;
   margin: 0 auto;
   width: 80%;
}
main aside article p:last-child {
   margin-top: 5px;
}
main aside article h1 {
   margin: 10px 0;
}

/* comments */

#comments {
   border-top: 1px dotted #ccc;
   font-size: 12px;
   margin-top: 40px;
}
.comment {
   width: 500px;
}
.comment_title {
   margin-bottom: 0.5em;
   font-weight: 600;
}
.comment::after {
   border-top: 1px solid #ccc;
   content: "";
   display: block;
   margin: 10px 0;
   width: 100px;
}
.comment_author {
   font-style: italic;
}

/* Footer
/* ============== */

footer {
   background-color: #666;
   color: #eee;
   font-size: smaller;
   padding: 10px;
   text-align: center;
}

footer a {
   color: #ccc;
}

footer p, footer ul  {
   margin: 10px 0;
}

footer ul {
   list-style: none;
   padding: 0;
}

footer li {
   display: inline-block;
}

footer ul a {
   display: inline;
   line-height: 24px;
   padding: 2px 5px;
}
footer li + li:before {
   content: ' | ';
   color: #999;
}
niet flexibel of responsive: horizontale scrollbar verschijnt

Stap 2: flexibel maken

Aanpassingen:

...
#wrapper {
   width: 900px;
   max-width: 900px;
   min-width: 240px;
   ...
}

header {
   height: 100px;
   padding-bottom: 40px;
}
  
#leftmenu {
   width: 190px;
   flex: 0 0 190px; 
}

#content {
   width: 710px;
   flex: 1 1 710px;
}

.content_picture {
   width: 450px;
   max-width: 450px;
   width: 100%;
}

.comment {
   width: 500px;
   width: 100%;
}
flexibel: geen horizontale scrollbar meer, maar nog niet responsive: content verschuift niet

Stap 3: media queries

Aanpassingen:

...
header {
   ...
   display: flex;
}

main {
   ...
   display: flex;
}

main aside {
   ...
   float: right;
   margin: 15px 0 10px 10px;
   width: 160px;
   margin: 15px 0 10px 0;
}
/* Media queries
/* ============== */

@media (min-width: 480px) {
   main aside {
      float: right;
      margin-left: 10px;
      width: 160px;
   }
   header {
      display: flex;
   }
}
@media (min-width: 600px) {
   main {
      display: flex;
   }
}
responsive: geen horizontale scrollbar meer, en content herschikt naargelang schermbreedte

Best practices (belangrijk!)