CSS Design

tussen []: optioneel, sterk aanbevolen voor wie wil verdergaan in web

gebruik pijltjestoetsen om te navigeren
dotted codepanels zijn editeerbaar

CSS

Eenheden

Overzicht

Eenheden gebruikt in deze cursus:

Eenheid Type Gerelateerd met Voorbeeld
px absoluut screen pixels p {font-size: 14px}
% percentage parent afmetingen of font size .left {width: 20%}
em percentage parent element font size p {font-size: 1.2em}
  • er zijn nog meer eenheden (rem, vmin, vmax, vw, vh) maar die worden niet gebruikt in deze cursus

px — definitie

  • De pixel staat voor pi(cture) el(ement), en komt op schermen meestal overeen met één gekleurde punt op het scherm (maar niet altijd: bij retina schermen bv. zijn dit er 4 per pixel).
  • De ware definitie is "kijkhoogte van 1/96 inch op gemiddelde armlengte" (ik verzin het niet):
    px definition
  • een pixel is dus eigenlijk een kijkhoek, geen afmeting; de maan is bijvoorbeeld 24.3px
  • voor de praktijk mag je de pixel gelijkstellen aan een beeldschermpixel

px — gebruik

  • De px wordt gebruikt voor vaste afmetingen, zoals borders, kleine afbeeldingen, knoppen...:
    input[type=submit] {
      border: 2px solid #666;
    }
    img.hamburger_icon {
      height: 22px;
      width: 22px;
    }
    .button {
      height: 20px;
      width: 120px;
    }
  • gebruik px niet voor flexibele elementen (i.e. die moeten meeschalen bij verschillende schermbreedtes) als kolommen, banners, foto's...; daarvoor gebruik je percentages (zie volgende slide)

% — definitie en gebruik

  • De % betekent percentage van parent afmetingen. Je kan het gebruiken om width en/of height van een child element in te stellen:
    img {
      max-width: 600px;
      width: 80%; /* 80% of the parent's width */
    }
    

em — definitie

em — definitie en gebruik

  • In CSS heeft em de betekenis percentage van de parent font-size. Daarmee kan je bepaalde waarden ingesteld op een child laten meeschalen met de parent font-size:
    <div class="review">
       <h3 class="review-title">Great hotel!</h3>
       <p>
         In friendship diminution instrument so.
         Son sure paid door with say them. Lorem
         ipsum dolor sit amet, consectetur
         adipiscing elit!
       </p>
       <img src="img/mugshot.jpg" alt="avatar">
     </div>
    Great hotel!

    In friendship diminution instrument so. Son sure paid door with say them. Lorem ipsum dolor sit amet, consectetur adipiscing elit!

    .review {
      border: 2px dotted #ccc;
      font-size: 14px; /* pas deze waarde aan! */
    }
    .review-title {
      font-size: 1.2em; /* schaalt mee */
    }
    .review p {
      font-size: 1em; /* schaalt mee */
    }
    .review img {
      width: 50px; /* schaalt niet mee */
    }

em — gebruik

  • De em is dus ideaal voor componenten die meeschalen met de parent, zoals widgets of andere onafhankelijke componenten. Probeer in onderstaande demo de font-size van de widget container te veranderen (en merk op hoe em overal gebruikt is in de widget):

em change

[rem — definitie]

  • De rem of “root em” is net zoals em een relatieve eenheid, maar dan de percentage van de <html> font-size.
  • Standaard is de font-size van <html> 16px, dus dan is 1rem = 16px. Volgende fragmenten zijn dus identiek (deel alle px waarden door 16):
    body { font-size: 14px; }
    h1 { font-size: 20px; }
    footer { font-size: 11px; }
    footer a { font-size: 12px; }
    body { font-size: 0.875rem; }
    h1 { font-size: 1.25rem; }
    footer { font-size: 0.6875rem; }
    footer a { font-size: 0.75rem;  }
  • kan interessant zijn in bepaalde gevallen die buiten het bereik van deze cursus vallen

[vw / vh / vmin / vmax]

  • De vw / vh / vmin / vmax staat voor percentage viewport width / height / kleinste / grootste, waarbij “viewport” het zichtbare browsergedeelte betekent.
  • Voorbeeld 1: smooth font rescaling:
    p {
      font-size: 2vw; /* teksthoogte = 2% viewport width, of ± 80 karakters per regel */
    }
  • Voorbeeld 2: een afbeelding zichtbaar houden
    img {
      max-height: 90vh; /* max. 90% viewport height */
      max-width: 90vw; /* max. 90% viewport width */
    }
    
  • hoofdzakelijk nuttig voor mobiele devices

Eenheden — samengevat

  • Welke eenheid gebruik je wanneer:
    • gebruik standaard px
    • gebruik % voor afmetingen die moeten meeschalen met de schermbreedte (kolommen bv.)
    • gebruik em voor onafhankelijke componenten als widgets

CSS

Fonts & Tekst

Wat is een font

  • Een font is een grafische weergave van tekst. CSS properties:
    • font-family: Arial, Courier New, Times New Roman...
    • font-size: 8px, 12px, 18px...
    • font-weight: lighter, normal, bold...; 100, 300, 500, 700, 900
    • font-style: italic, normal
    • color: #900, Navy, rgba(100, 50, 25, 0.7)...

Font properties

  • Code voorbeeld in CSS:
    p {
      color: #5a4c34;
      background-color: #f0ede3;
      font-size: 14px;
      font-family: Lato, Arial, sans-serif; /* provide several alternatives */
      font-weight: bold; /* default: normal */
      font-style: normal; /* also try italic */
      letter-spacing: 2px; /* add 2px extra space between letters */
      line-height: 1.6; /* 160% of character height */
      padding: 5px 10px;
      text-shadow: 2px 2px 15px #666;
      text-transform: capitalize;
    }
    a {
      text-decoration: none; /* onderlijnen of niet; werkt alleen bij links */
      color: #aa8938;
    }
    a:hover {
      text-decoration: underline;
    }

    In friendship diminution instrument so. Son sure paid door with say them. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec iaculis malesuada mi, nec pharetra elit vehicula et. Donec consectetur porttitor mauris mollis facilisis. Phasellus et lorem augue, eget eleifend quam. Sed ac bibendum lorem. Praesent molestie lobortis elementum. Nam sed magna eget quam ullamcorper semper. Ut molestie faucibus accumsan. Donec sodales rhoncus augue ac aliquam. In hac habitasse platea dictumst.

Commerciële fonts

  • Fonts worden met de hand ontworpen, karakter per karakter:

  • bedenk hoeveel werk dit is: alle letters, getallen, accenten, interpunctie, hoofd- / kleine letters... en dat in alle tallen, alle vetdiktes en stijlen!
  • licenties voor kwaliteitsvolle commerciële fonts zijn daarom vaak zeer duur

Gratis fonts

  • Gelukkig zijn er genoeg gratis en open source lettertypes te vinden. Google heeft een uitstekende collection die je kan downloaden of zelfs gewoon hotlinken. Selecteer je font, en link het met één regel in de <head>:
    <html>
    <head>
      <!-- kopieer de Google Font link hier -->
      <link href="https://fonts.googleapis.com/css?family=Spicy+Rice" rel="stylesheet">
      <style>
        p {
          font-family: 'Spicy Rice', sans-serif; /* gebruik je nieuw font hier */
          font-size: 30px;
          line-height: 1.8;
        }
      </style>
    </head>
    <body>
      <p>Wie werkten meestal men menigte bersawa. Om monopolies ad nu mislukking interesten verscholen
      smeltovens. Brandhout mee snelleren geschiedt bezorgden aandeelen den are. Dat treffen gomboom zekeren
      tot fortuin gelaten stellen. Het ziet niet lage deze het per zes ipoh.</p>
    </body>
    </html>
    

Help! Mijn font laadt niet

  • Zaken die kunnen foutgaan:
    • een font moet alle karakters bevatten die je wil gebruiken
    • een font moet alle weergaves bevatten (vet, schuin...) die je nodig hebt
    • als je font niet correct gelinkt is, valt het terug op een standaardfont, meestal het lelijke Times New Roman
  • Je kan controleren welk font effectief gebruitk wordt via de Chrome inspector (beneden rechts, tab ‘Computed’, onder ‘Rendered fonts’):

[Variable fonts (1)]

  • Van klassieke lettertypes kan je een paar eigenschappen aanpassen als de grootte en (in stappen) het gewicht. Voorbeeld (met beetje Javascript):
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="utf-8">
       <title>Lato</title>
       <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
       <style>
          label {
             display: block;
             font-family: Lato;
             margin: 10px;
          }
          #text {
             border: 2px ridge; 
             font-family: Lato;
             padding: 20px;
          }
       </style>
    </head>
    <body>
       <div id="controls">
          <label>Kleur: <input type="color" id="color" value="#000000"></label>
          <label>Grootte: <input type="range" id="size" min="4" max="60" value="14" step="1"></label>
          <label>Gewicht: <input type="range" id="weight" min="100" max="900" value="400" step="100"></label>
       </div>
       <p id="text">
          In no impression assistance contrasted. Manners she wishing justice 
          hastily new anxious. At discovery discourse departure objection we.
       </p>
       <script>
          // aliases
          const color = document.querySelector('#color');
          const size = document.querySelector('#size');
          const weight = document.querySelector('#weight');
    
          // apply all settings
          function applyAll() {
             text.style.color = color.value;
             text.style.fontSize = size.value + 'px';
             text.style.fontWeight = weight.value;
          }
    
          // attach events
          color.addEventListener('input', applyAll);
          size.addEventListener('input', applyAll);
          weight.addEventListener('input', applyAll);
       </script>
    </body>
    </html>
    

[Variable fonts (2)]

  • Variable fonts hebben veel meer tweaking mogelijkheden, b.v. het prachtige Decovar font:
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="utf-8">
       <title>Variable fonts</title>
       <style>
          @font-face {
             font-family: Decovar;
             src: url(fonts/DecovarAlpha-VF.ttf) format("truetype");
          }
          label {
             display: block;
             font-family: Lato;
             margin: 10px;
          }
          #text {
             border: 2px ridge; 
             font-family: Decovar;
             font-size: 30px;
             font-variation-setting: 'WMX2' 0, 'TRMG' 0, 'BLDA' 0;
             padding: 20px;
          }
       </style>
    </head>
    <body>
       <div id="controls">
          <label>Kleur: <input type="color" id="color" value="#000000"></label>
          <label>Grootte: <input type="range" id="size" min="10" max="60" value="30" step="1"></label>
          <label>Instelling 1: <input type="range" id="setting1" min="0" max="1000" step="1" value="0"></label>
          <label>Instelling 2: <input type="range" id="setting2" min="0" max="1000" step="1" value="0"></label>
          <label>Instelling 3: <input type="range" id="setting3" min="0" max="1000" step="1" value="0"></label>
          <p> → meer instellingen zie  <a href="https://www.axis-praxis.org/specimens/decovar">deze pagina</a></p>
       </div>
       <p id="text">
          In no impression assistance contrasted. Manners she wishing justice 
          hastily new anxious. At discovery discourse departure objection we.
       </p>
       <script>
          // aliases
          const color = document.querySelector('#color');
          const size = document.querySelector('#size');
          const setting1 = document.querySelector('#setting1');
          const setting2 = document.querySelector('#setting2');
          const setting3 = document.querySelector('#setting3');
          const text = document.querySelector('#text');
    
          // apply all settings
          function applyAll() {
             text.style.color = color.value;
             text.style.fontSize = size.value + 'px';
             text.style.fontVariationSettings = `'WMX2' ${setting1.value}, 'TRMG' ${setting2.value}, 'BLDA' ${setting3.value}`;
          }
    
          // attach events
          color.addEventListener('input', applyAll);
          size.addEventListener('input', applyAll);
          setting1.addEventListener('input', applyAll);
          setting2.addEventListener('input', applyAll);
          setting3.addEventListener('input', applyAll);
       </script>
    </body>
    </html>

[Variable fonts (3)]

  • Variabel fonts kunnen ook symbolen bevatten. Voorbeeld met het Zycon font:
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="utf-8">
       <title>Variable fonts — Zycon</title>
       <style>
          @font-face {
             font-family: Zycon;
             src: url(fonts/Zycon.woff2);
          }
          label {
             display: block;
             font-family: Lato;
             margin: 10px;
          }
          #text {
             border: 2px ridge; 
             font-family: Zycon;
             font-size: 42px;
             padding: 20px;
          }
       </style>
    </head>
    <body>
       <div id="controls">
          <label>Kleur: <input type="color" id="color" value="#000000"></p>
          <label>Grootte: <input type="range" id="size" min="10" max="60" value="42" step="1"></p>
          <label>T1: <input type="range" id="setting1" min="0" max="1" value="0" step="0.01" value="0"></label>
          <label>T2: <input type="range" id="setting2" min="0" max="1" value="0" step="0.01" value="0"></label>
          <label>T3: <input type="range" id="setting3" min="0" max="1" value="0" step="0.01" value="0"></label>
          <label>T4: <input type="range" id="setting4" min="0" max="1" value="0" step="0.01" value="0"></label>
          <label>M1: <input type="range" id="setting5" min="0" max="1" value="0" step="0.01" value="0"></label>
          <label>M2: <input type="range" id="setting6" min="0" max="1" value="0" step="0.01" value="0"></label>
       </div>
       <p id="text">☀ ✯ ➟ ⬤ 🌝 🏵 🐈 🐕 🐢 💡🔒 🕛 🖐 🚴 🦉 🦎 </p>
       <script>
          // aliases
          const color = document.querySelector('#color');
          const size = document.querySelector('#size');
          const setting1 = document.querySelector('#setting1');
          const setting2 = document.querySelector('#setting2');
          const setting3 = document.querySelector('#setting3');
          const setting4 = document.querySelector('#setting4');
          const setting5 = document.querySelector('#setting5');
          const setting6 = document.querySelector('#setting6');
          const text = document.querySelector('#text');
    
          // apply all settings
          function applyAll() {
             text.style.color = color.value;
             text.style.fontSize = size.value + 'px';
             text.style.fontVariationSettings = `'T1  ' ${setting1.value},'T2  ' ${setting2.value},'T3  ' ${setting3.value},'T4  ' ${setting4.value},'M1  ' ${setting5.value},'M2  ' ${setting6.value}`;
          }
    
          // attach events
          color.addEventListener('input', applyAll);
          size.addEventListener('input', applyAll);
          setting1.addEventListener('input', applyAll);
          setting2.addEventListener('input', applyAll);
          setting3.addEventListener('input', applyAll);
          setting4.addEventListener('input', applyAll);
          setting5.addEventListener('input', applyAll);
          setting6.addEventListener('input', applyAll);
       </script>
    </body>
    </html>
    

[Variable fonts (4)]

  • Nog een laatste voorbeeld, gecombineerd met een animatie:
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="utf-8">
       <title>Variable fonts — Zycon</title>
       <style>
          @font-face {
             font-family: Zycon;
             src: url(fonts/Zycon.woff2);
          }
          #text {
             font-family: Zycon;
             font-size: 180px;
             font-variation-settings: "T1  " 0, "T2  " 0, "T3  " 0, "T4  " 0, "M1  " 0, "M2  " 0;
             animation: variation 0.3s linear infinite;
          }
          @keyframes variation {
             0% {
                font-variation-settings: "T1  " 0, "T2  " 0, "T3  " 0, "T4  " 0, "M1  " 0, "M2  " 0;
             }
             100% {
                font-variation-settings: "T1  " 0, "T2  " 0, "T3  " 0, "T4  " 0, "M1  " 1, "M2  " 0;
             }
          }
       </style>
    </head>
    <body>
       <p id="text">🚴</p>
    </body>
    </html>

[CSS] Blend modes

  • Meng lagen zoals in Photoshop, zie https://developer.mozilla.org/
  • background-image: url(img/kaynewest.jpg);
    background-color: #add8e6; 
    background-blend-mode: darken; /* probeer ook lighten */
    background-size: cover;
    

CSS

Kleuren & achtergronden

Hexadecimale notatie

  • De meest gebruikte kleurnotatie is #RRGGBB hexadecimaal:
    p {
      background-color: #ffcccc;
      color: #d2003c;
    }

    Lorem Ipsum

  • Als je hexcode #xxyyzz is, kan je de verkorte notatie #xyz gebruiken:
    p {
      background-color: #fcc; /* #ffcccc */
      color: #c09; /* #cc0099 */
    }

Hexcodes lezen

  • De hexadecimale kleurnotatie is een combinatie van rood, groen en blauw: #d2003c bijvoorbeeld betekent (d=13)*16 + 2 rood, 0 groen en 3*16 + (c=12) blauw, of (210, 0, 60) in (r, g, b) notatie. Wil je vlot kleurcodes leren lezen? Bekijk dan deze briljante talk op de dotCSS conferentie van 2018 in Parijs:

Alfakanaal

  • Het alfakanaal stelt de transparantie van een kleur voor
  • Enkele notaties met alfa: HSLA (hue-saturation-luminosity-alpha), #RRGGBBAA en RGBA
    p {
      background-color: hsla(128, 75%, 33%, 0.5); /* 50% opacity */
      border: 4px dashed #FFa500BF; /* #FFA500 = orange, BF = 75% opacity */
      color: rgba(50, 44, 150, 0.9); /* 90% opacity */
    }

    ALPHA EXAMPLE

Mnemonische notatie

  • Er bestaat ook zoiets als de weinig professionele en dubbelzinnige mnemonische notatie:
    p {
      background-color: Maroon; /* geen idee welke kleur dit is */
      border: 2px solid Orange; /* ok, die snap ik nog */
      color: MistyRose; /* wat in 's hemelsnaam is een misty rose? */
    }

    Lorem Ipsum

  • dit doet allemaal wat denken aan een verfwinkel; mnemonische notatie is voor watjes

Chrome color picker

  • Chrome heeft een prima ingebouwde colorpicker met live preview:

Achtergronden

  • Achtergronden maak je met de verschillende properties van background:
  • div {
      background-color: #ccc; /* achtergrondkleur */
      background-image: url(img/02_design/grass.png); /* link naar de afbeelding zelf */
      background-position: left bottom; /* andere waarden: center, pixels of procenten... */
      background-size: 100% 100%; /* andere waarden: 100%, cover, contain, auto, pixels... */
      background-repeat: no-repeat; /* andere waarden: repeat, repeat-x, repeat-y */
    }

Transities

  • Maak CSS overgangen geleidelijk, “smooth”, met de transition property:
  • div {
      background-color: #ccc;
      transition: background 0.5s, width 1s; /* transitie voor achtergrond en breedte */
      width: 200px;
    }
    div:hover {
      background-color: #ee3c87;
      border-radius: 0 15px 15px 0;
      color: white;
      width: 300px;
    }
    
    hover me!

[Gradiënten]

  • Gebruik een gradiënt als achtergrond met linear-gradient:
  • p {
      background: linear-gradient(
         to bottom,
         #00abeb 10%,
         white 30%,
         yellow 50%,
         #66cc00 70%
      )
    }

    GRADIENT EXAMPLE

[Filters]

  • CSS biedt met de filter property een aantal basisfilters als blur, grayscale, brightness, contrast, sepia. Een voorbeeld met grayscale (hover over de afbeelding):
  • img {
      cursor: pointer;
      filter: grayscale(100%);
      transition: filter 0.5s;
    }
    img:hover {
      filter: grayscale(0%);
    }
    

[Transformaties]

  • Roteer, rek uit en herschaal elementen rond de X, Y en Z-as met de transform property:
  • #contactbox {
      background-color: #eee;
      transform: rotate(8deg) skewY(15deg);
      width: 250px;
    }
    

    Contacteer me!

[Animaties (1)]

  • Definieer keyframes, properties en easing (= animatiecurve) met @keyframes:
  • <!DOCTYPE html>
    <head>
      <meta charset="utf-8" />
      <title>Animatie demo</title>
      <style>
        #scene {
          width: 800px;
          border: 2px solid #999;
          margin: 20px auto;
          height: 200px;
          overflow: hidden;
        }
        #busBig {
          background-image: url(img/busBig.png);
          width: 247px;
          height: 106px;
          margin-left: -300px;
          margin-top: 50px;
          animation: moveBus 3s 1 ease-in-out;
        }
        @keyframes moveBus {
          0% { margin-left: -300px; }
          50% { margin-left: 70px; }
          100% { margin-left: 2000px; }
        }
      </style>
    </head>
    <body>
      <div id="scene">
        <div id="busBig" class="layer"></div>
      </div>
    </body>
    </html>

[Animaties (2)]

  • Animaties gecombineerd met transformaties en een beetje Javascript (Chrome):
  • <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="utf-8">	
       <title>Morphing Power Cubes</title>
       <style>
          body {
             background-color: black;
          }
          #container {
             perspective: 800px; 
             perspective-origin: 50% 0;
          }
          #stage {
             transition: transform 2s;
             transform-style: preserve-3d;
          }
          #cube {
             height: 200px;
             margin: 0 auto;
             position: relative;
             top: 100px;
             transform-style: preserve-3d;
             width: 200px;
          }
          .plane {
             background-color: rgba(255, 255, 255, 0.6);
             border: 1px solid white;
             border-radius: 12px;
             font-size: 165px;
             height: 200px;
             opacity: 0.5;
             position: absolute;
             text-align: center;
             width: 200px;
          }
          #cube.animate {
             animation: spin 8s infinite linear;
          }
          @keyframes spin {
             from { transform: rotateY(0); }
             to   { transform: rotateY(-360deg); }
          }
          .one {
             transform: scale3d(1.2, 1.2, 1.2) rotateX(90deg) translateZ(100px);
          }
          .two {
             transform: scale3d(1.2, 1.2, 1.2) translateZ(100px);
          }
          .three {
             transform: scale3d(1.2, 1.2, 1.2) rotateY(90deg) translateZ(100px);
          }
          .four {
             transform: scale3d(1.2, 1.2, 1.2) rotateY(180deg) translateZ(100px);
          }
          .five {
             transform: scale3d(1.2, 1.2, 1.2) rotateY(-90deg) translateZ(100px);
          }
          .six {
             transform: scale3d(1.2, 1.2, 1.2) rotateX(-90deg) translateZ(100px) rotate(180deg);
          }
       </style>
    </head>
    <body>
       <div id="container">
          <div id="stage">
             <div id="cube" class="animate">
                <div class="plane one">1</div>
                <div class="plane two">2</div>
                <div class="plane three">3</div>
                <div class="plane four">4</div>
                <div class="plane five">5</div>
                <div class="plane six">6</div>
             </div>
          </div>
          <div id="controls">
             <p><input type="range" id="slider" min="0.1" max="20" step="0.1"></p>
             <p><button id="btnStartStop">without animation</button></p>			
          </div>
       </div>
       <script>
          document.querySelector('#slider').addEventListener('input', function() {
          document.querySelector('#cube').style.animationDuration = `${this.value}s`;  	
       });
       document.querySelector('#btnStartStop').addEventListener('click', function() {
          document.querySelector('#cube').classList.toggle('animate');
          this.innerHTML = this.innerHTML == 'without animation' ? 'with animation' : 'without animation';
       });
       </script>
    </body>
    </html>
  • zie ook b.v. de pure HTML/CSS stopwatch demo, CSS experimenten door Mark Robbins...

CSS

Border, padding & margin

Border, padding & margin

  • Definities (van buiten naar binnen):
    • margin: ruimte buiten een element
    • border: lijnen rondom een element
    • padding: ruimte binnen een element
    • content: de inhoud zelf

box model

Border (1)

  • We beginnen met twee paragrafen in een <div>, met wat CSS:
    <div>
      <p>In friendship diminution instrument so. Son sure paid door with say them.</p>
      <p>Fact are size cold why had part. If believing or sweetness otherwise.</p>
      <p>Unpacked now declared put you confined daughter improved.</p>
    </div>
    
    div {
      background-color: #eee;
    }
    p {
      background-color: #ccc;
      margin: 0; /* browserdefault uitzetten */
    }
    

    In friendship diminution instrument so. Son sure paid door with say them.

    Fact are size cold why had part. If believing or sweetness otherwise in we forfeited.

    Unpacked now declared put you confined daughter improved.

Border (2)

  • Voegen we wat borders toe:
    div {
      background-color: #eee;
      border: 5px dotted #900;
    }
    p {
      background-color: #ccc;
      border: 1px solid black;
      margin: 0;
    }
    

    In friendship diminution instrument so. Son sure paid door with say them.

    Fact are size cold why had part. If believing or sweetness otherwise in we forfeited.

    Unpacked now declared put you confined daughter improved.

Border (3)

  • Opmerking: je kan verschillende borderstijlen specifiëren voor de vier kanten
    div {
      background-color: #eee;
      border: 5px dotted #900;
      border-left-color: #009;
      border-right-style: dashed;
      border-top-width: 2px;
    }
    p {
      background-color: #ccc;
      border-bottom: 1px solid black;
      margin: 0;
    }
    

    In friendship diminution instrument so. Son sure paid door with say them.

    Fact are size cold why had part. If believing or sweetness otherwise in we forfeited.

    Unpacked now declared put you confined daughter improved.

Padding

  • Voegen we nu padding toe binnen de paragrafen en binnen de <div>:
    div {
      background-color: #eee;
      border: 5px dotted #900;
      padding: 20px 40px; /* vert-hor */
    }
    p {
      background-color: #ccc;
      border: 1px solid black;
      margin: 0;
      padding: 10px;
    }

    In friendship diminution instrument so. Son sure paid door with say them.

    Fact are size cold why had part. If believing or sweetness otherwise in we forfeited.

    Unpacked now declared put you confined daughter improved.

Margin

  • Tenslotte voegen we een margin toe onder alle paragrafen, behalve de laatste:
    div {
     background-color: #eee;
     border: 5px dotted #900;
     padding: 20px 40px;
    }
    p {
     background-color: #ccc;
     border: 1px solid black;
     margin: 0;
     margin-bottom: 10px;
     padding: 10px;
    }
    /* laatste paragraaf geen margin onder  */
    p:last-child {
     margin-bottom: 0;
    }

    In friendship diminution instrument so. Son sure paid door with say them.

    Fact are size cold why had part. If believing or sweetness otherwise in we forfeited.

    Unpacked now declared put you confined daughter improved.

Margin of padding? (1)

  • In plaats van padding op de <div>, hadden we ook margin op de <p>'s kunnen gebruiken voor de ruimte tussen de rood gestippelde rand en paragrafen. Het resultaat is gelijk:
    div {
     background-color: #eee;
     border: 5px dotted #900;
    }
    p {
     background-color: #ccc;
     border: 1px solid black;
     margin: 10px 40px;
     padding: 10px;
    }
    /* eerst paragraaf 20px margin boven  */
    p:first-child {
     margin-top: 20px;
    }
    /* laatste paragraaf 20px margin onder  */
    p:last-child {
     margin-bottom: 20px;
    }

    In friendship diminution instrument so. Son sure paid door with say them.

    Fact are size cold why had part. If believing or sweetness otherwise in we forfeited.

    Unpacked now declared put you confined daughter improved.

Margin of padding? (2)

  • Zoals vorig voorbeeld aantoont, kan je soms kiezen tussen margin en padding.
  • Eigenlijk maakt het niet zoveel uit wat je kiest, zolang het maar werkt, maar om een houvast te geven hanteren we in deze cursus volgende vuistregels:
    1. denk standaard aan margins, dus ruimte tussen elementen
    2. denk enkel aan padding bij ruimte binnen elementen, dus tussen rand en de inhoud
    3. denk van buiten naar binnen: liever margin/padding op de parent, dan margin/padding op de child
    4. denk van linksboven naar rechtsonder: liever margin bottom/right op een element, dan top/left op het volgende (dit geldt ook voor borders: b.v. liever een border onder dan boven een element)
  • Zoals altijd bij vuistregels, zijn er uitzonderingen:
    • bij een menu (ul > li > a) gebruik je beter padding op de <a> dan op de <li> om het klikgebied te vergroten (overtreding vuistregel 3)
    • bij een "lees meer" knop onderaan een tekst is het makkelijker een margin-top te gebruiken op de knop dan een margin-bottom op de vorige paragraaf (overtreding vuistregel 4)
    • ...
  • volg zoveel mogelijk de vuistregels, maar gebruik je gezond verstand

Lekkende margin (1)

  • Volgens vuistregel 3 stel je dus beter padding op de parent in dan margin op de child. Een raar probleem dat optreedt als je deze regel niet volgt is de zgn. "lekkende margin".
    Neem volgend voorbeeld (klik op "Toon in popup"):
    <html>
    <head>
      <style>
        body { margin: 0; }
        header { background-color: #ccc; }
        header p { margin: 20px; }
      </style>
    </head>
    <body>
      <header>
        <p><a href="#">klantenzone</a></p>
      </header>
    </body>
    </html>
    
  • de <header> (donkergrijze achtergrond) is naar beneden geduwd!?
  • dit komt door de margin van de <p>, die boven (en onder) uit zijn parent "lekt"
  • in CSS is dit "normaal" gedrag als parents geen border of padding hebben

Lekkende margin (2)

  • Je kan het oplossen door de <p> margin te vervangen door <header> padding (klik weer op "Toon in popup"):
    <html>
    <head>
      <style>
        body { margin: 0; }
        header { background-color: #ccc; padding: 20px; }
        header p { margin: 0; }
      </style>
    </head>
    <body>
      <header>
        <p><a href="#">klantenzone</a></p>
      </header>
    </body>
    </html>
    
  • denk aan vuistregel 3 ("van buiten naar binnen"): beter padding op de <header> dan margin op de <p>!

Margin & padding regels (1)

  • Margins volgen rare regels:
    • ongepositioneerd, blocklevel: horizontale margins tellen op, verticale margins niet (de grootste waarde telt)
    • gepositioneerd, blocklevel: alle margins tellen op
    • inline elementen: verticale margins worden genegeerd, horizontale tellen op
  • Ook paddings volgen soms rare regels:
    • inline elementen: verticale margins worden genegeerd; verticale paddings overlappen bovenliggende content maar niet onderliggende content
  • → zie deze samenvattende demo

Margin & padding regels (2)

  • Gelukkig hoef je al die regels niet te onthouden. Vermijd gewoon problemen met volgende vuistregels:
    • stel geen verticale paddings of margins in op inline elementen
    • vermijd lekkende margins door paddings te gebruiken waar je kan
    • bovenal: gebruik systematisch de chrome inspector!

box model

CSS

Het box model

Box model

  • Het model met margin-border-padding-content en alle afmetingen noemt men ook wel het box model
  • Vreemd genoeg hebben de properties width en height enkel betrekking op de content, zonder borders and paddings. In onderstaand voorbeeld bv. is de uiteindelijke breedte niet de ingestelde 150px, maar 162px (contentbreedte + 2x padding + 2x borderdikte):
box model
div {
  width: 150px; /* totale breedte is 162px */
  padding: 5px;
  border: 1px solid black;
}

Box model probleem

  • De echte breedte is dus groter dan ingesteld, doordat padding en border erbij geteld worden. Dit kan problemen geven. Neem volgend voorbeeld met twee kolommen van 50%, waarvan de linker een border rechts en een padding heeft:
    <html>
    <head>
      <style>
        .col {
          width: 50%;
        }
        .col:first-child {
          border-right: 4px dotted #999;
          padding: 0 30px;
        }
        #wrapper {
          border: 4px solid #999;
          display: flex; /* layout met flex, zie volgende les */
          height: 300px;
          width: 500px;
        }
      </style>
    </head>
    <body>
      <div id="wrapper">
        <div class="col">kolom 1</div>
        <div class="col">kolom 2</div>
      </div>
    </body>
    </html>
    
    • de linkerkolom is breder dan de rechter, hoewel beiden op 50% ingesteld staan

Oplossing 1: gebruik calc()

  • Oplossing 1: trek borders en paddings af gebruikmakend van de calc() functie:
    <html>
    <head>
      <style>
        .col {
          width: 50%;
        }
        .col:first-child {
          border-right: 4px dotted #999;
          padding: 0 30px;
          width: calc(50% - 64px); /* gebruik calc(): 50% - 2x30px - 4px */
        }
        #wrapper {
          border: 4px solid #999;
          display: flex; /* layout met flex, zie volgende les */
          height: 300px;
          width: 500px;
        }
      </style>
    </head>
    <body>
      <div id="wrapper">
        <div class="col">kolom 1</div>
        <div class="col">kolom 2</div>
      </div>
    </body>
    </html>
    

Oplossing 2: gebruik box-sizing

  • Oplossing 2: corrigeer het box model met de box-sizing property
    <html>
    <head>
      <style>
        * {
          box-sizing: border-box; /* normaal content-box - voila! nu is 50% ook echt 50% */
        }
        .col {
          width: 50%;
        }
        .col:first-child {
          border-right: 4px dotted #999;
          padding: 0 30px;
        }
        #wrapper {
          border: 4px solid #999;
          display: flex; /* layout met flex, zie volgende les */
          height: 300px;
          width: 500px;
        }
      </style>
    </head>
    <body>
      <div id="wrapper">
        <div class="col">kolom 1</div>
        <div class="col">kolom 2</div>
      </div>
    </body>
    </html>
    
  • dit spaart een hoop hoofdbrekens
  • zet daarom de box-sizing fix altijd bovenaan je CSS code!

Width & height op inline elements

  • Belangrijk: je kan width of height niet instellen op inline elementen. Eventuele waarden worden genegeerd. Wil je dit toch, dan moet je het eerst blocklevel maken met de display property. Voorbeeldcode om een (inline) link het uitzicht van een button te geven:
    a {
      /* maak blocklevel, en stel breedte in */
      display: block;
      width: 200px;
    
      /* rest van het button design */
      background-color: #A2C355;
      border: 2px solid #A2C355;
      border-radius: 2px;
      color: #fff;
      cursor: pointer;
      font-size: 16px;
      line-height: 1.8;
      padding: 9px 24px;
      text-align: center;
      text-decoration: none;
      text-transform: uppercase;
      transition: all 0.3s; /* smooth transition of all properties */
    }
    a:hover {
      background-color: white;
      color: #A2C355;
    }
    

Box shadow & radius

  • Schaduw en radius effects:
    box-shadow: 10px 10px 5px #888;
    border-radius: 50px 5px 5px 5px;
    

CSS

Weergave

Opacity

  • Maak een element (gedeeltelijk) transparant:
    p {
      background-color: #000;
      color: #fff;
      opacity: 0.4; /* verander deze waarde */
    }
    <div id="parent">

    <p> just some paragraph

Display: default

  • Inline elementen gedragen zich in het boxmodel standaard anders dan blocklevel elementen. Vergelijk een link (inline) met een paragraaf (blocklevel):
    a, p {
      height: 60px; /* werkt niet voor de link */
      padding: 20px; /* werkt niet goed bij de link: overlapt met andere elementen */
      width: 40%; /* werkt niet voor de link */
    }
    <div id="parent">
    <a> just some link

    <p> just some paragraph

  • op inline elementen kan je geen hoogte of breedte instellen
  • op inline elementen werkt verticale padding of margin niet goed (overlapt met andere elementen)
  • blockevel elementen nemen standaard de volledige breedte in, inline elementen de breedte van de content

Display: none

  • Verwijdert een element volledig (en het neemt zelfs geen ruimte meer in):
    a, p {
       display: none; 
       padding: 10px; 
       height: 40px;
       width: 40%;
    }
    <div id="parent">
    <a> just some button

    <p> just some paragraph

Display: block

  • Maakt van een element een blocklevel element:
    a, p {
       display: block; /* andere waarden: none, inline, inline-block */
       padding: 10px; 
       height: 40px;
       width: 40%;
    }
    <div id="parent">
    <a> just some button

    <p> just some paragraph

  • je kan nu hoogte, breedte en verticale margins en paddings instellen op de link

Display: inline

  • Omgekeerd kan je van elementen ook inline elementen maken; ze komen dan naast elkaar, net zoals gewone inline elementen:
    a, p {
       display: inline; /* andere waarden: none, block, inline-block */
       padding: 10px; 
       height: 40px;
       width: 40%;
    }
    <div id="parent">
    <a> just some button

    <p> just some paragraph

  • je kan nu geen hoogte, breedte en verticale margins en paddings meer instellen op de paragraaf

Display: inline-block

  • Dit is een combinatie van blocklevel en inline: je kan wel afmetingen, margins en paddings normaal instellen (blocklevel), maar ze kunnen naast elkaar staan en nemen de breedte van de content in (inline):
    a, p {
       display: inline-block; /* andere waarden: none, inline, block */
       padding: 10px; 
       height: 40px;
       width: 40%;
    }
    <div id="parent">
    <a> just some button

    <p> just some paragraph

  • je kan nu hoogte, breedte en verticale margins en paddings instellen op de link

[Visibility]

  • Maak een element onzichtbaar (maar het neemt nog wel ruimte in):
    p {
      visibility: hidden; /* standaardwaarde: visible; */
    }
    <div id="parent">

    <p> just some paragraph

  • zelfde resultaat als opacity: 0

CSS

[Tekst vervangen]

[Tekst vervangen]

  • Soms gebeurt het dat je een tekst in HTML wil vervangen door een afbeelding of grafisch element, bijvoorbeeld een titel, header, link... De werkwijze is als volgt:
    <h1><a href="#">Your Logo Here</a></h1>
    
    h1 a {
      background-image: url(img/logo.jpg); /* stel achtergrondafbeelding in */
      background-size: 100% 100%; /* maak de afbeelding passend */
      display: block; /* enkel block elementen kunnen width / height hebben */
      height: 161px; /* stel in op de hoogte van de afbeelding */
      overflow: hidden;  /* verberg tekst die uit de container vloeit */
      text-indent: 100%; /* duw de tekst uit de container */
      white-space: nowrap; /* vermijd tekstomloop */
      width: 214px; /* stel in op de breedte van de afbeelding */
    }
    
Odisee logo