html

HTML - Positioneren met flexbox

1. Flexbox

We gaan nu verder met het maken van de website en hiervoor zullen we een flexibele layout gebruiken met behulp van CSS Flexible Layout Box, in de volksmond bekend als Flexbox. Dit is een lay-outmodel om items in een rij of kolom te plaatsen waarbij een aantal zaken automatisch worden ingesteld. We hebben in deel 2 flexbox ook al gebruikt zoals bijvoorbeeld met de code display: flex. In dit deel werken we het verder uit en zullen we ontdekken wat er erg handig aan is.

Op basis van Flexbox gaan we onze website nu verder vorm gaan geven. We zullen daarbij ook een nieuwe manier geven voor een veel overzichtelijkere css.

Verder zijn twee zaken van belang:

  1. Je maakt vanaf het begin je eigen website door in principe af te wijken van de methode maar dusdanig dat je deze wel kunt blijven volgen. Het doel van dit deel is het maken van een website op basis van zogenaamde cards.
  2. Je begint altijd met het maken van een layout voor mobiele schermen en pas daarna pas je voor andere, grotere, schermen de lay-out aan. We zullen dit o.a. zien als we met een media-query  gaan werken.

2. CSS opnieuw instellen

We beginnen met het maken van een zogenaamde reset.css. Deze css hebben we gekopieerd van deze website en dit stelt een aantal zaken logischer in dan de standaard css. Je kunt in bovenstaande link altijd de laatste versie vinden. Kopieer de laatste versie en maak de reset.css. Plaats deze file in de css-map.

In het vorige deel hadden we de navbar ingesteld met een embedded style. Alle css die begint met het <nav> element verplaatsen we dit naar navbar.css. Bovenin vinden we nog een style wat begint met *. Hiervan hebben een deel al in de reset.css ingesteld dus dit mag worden verwijderd. Dan rest alleen nog het instellen van het font voor de hele website. Hiervoor maken we layout.css met nog enkele instellingen.

body {
    font-family: 'Poppins', sans-serif;
    background-color: var(--main-background);
}

h1 {
     font-size: 150%;
     font-weight: bold;
}

h2 {
    font-size: 125%;
    font-weight: bold;
}

Hoe krijgen we nu al die css-files werkend? Dat kan met behulp van een import vanuit style.css en dit bestandje plaatsen we in de root van je webapplicatie, dus naast index.xhtml.

@import "css/reset.css";
@import "css/layout.css";
@import "css/navbar.css";

Voor een volledig overzicht van alle bestanden en mapjes kun je deze zip downloaden. Voorbeeld 15 vind je hier. Merk op dat hier en daar de layout enigszins is aangepast.

3. Een card als basis

Voor de layout op de pagina gebruiken we een zogenaamde card. Een card wordt vaak gebruikt voor een onderwerp. Op WSchools vinden we twee voorbeelden van cards:

https://images.computational.nl/galleries/html/2022-09-15_08-57-46.png

De basis html van onze card is als volgt:

<main>
    <div class="centered">
        <section class="cards">
            <article class="card">
                <a href="#">
                    <figure>
                        <img src="images/who_are_you.png" alt=""/>
                    </figure>
                    <div class="card-content">
                        <h2>Header</h2>
                        <p>
                           Voor de layout op de pagina gebruiken we een 
                            card. Een card wordt vaak gebruikt  voor een 
                            onderwerp.
                        </p>
                    </div><!-- .card-content -->
                </a>
            </article><!-- .card -->
        </section>
    </div>
</main>

Voor de content op de pagina gebruiken we het <main> element. Deze wordt precies onder het <nav> element geplaatst.  Binnen de <main> plaatsen we een <div> waarin we een class "centered" hebben gedefinieerd. De css code hiervan is:

.centered {
    display: flex;
    justify-content: center;
}

Dit maakt dat alle elementen binnen de class centered in het midden gaan zweven. Deze code wordt in layout.css gemaakt. De afbeelding staat hier.

In het <main> element stellen we een padding in:

main {
    padding: 1rem;
}

In de html-code vind je ook een <figure> element. Zowel de figure als de image kunnen we nu met CSS als volgt opmaken:

img {
    width: 100%;
    height: auto;
}

figure {
  padding: 0.2rem;
}

Door de image een breedte van 100% te geven en een automatische hoogte, schaalt deze netjes mee als het scherm kleiner wordt.

Het resultaat van deze les is te zien in voorbeeld 16.

4. Variabelen en imports

In het voorbeeld van de vorige les ziet de stylesheet styles.css er als volgt uit:

@import "css/reset.css";
@import "css/layout.css";
@import "css/navbar.css";
@import "css/card.css";

:root {
  --main-background:beige;
  --background-hover: #0966C2;
  --background-nav: #F3BA64;
  --background-nav-border: orange;
}

Merk op dat we

body {
    font-family: 'Poppins', sans-serif;
    background-color: var(--main-background);
}

als meervoud hebben geschreven. Dat komt omdat het verwijst naar meerere stylesheets. De regel @import "css/reset.css"; houdt in dat er een aparte stylesheet reset.css is gemaakt in het mapje css. Dit geldt ook voor de overige stylesheets. We zien hier dat we de css in onderdelen verdelen. In onderstaande links kun je de structuur van voorbeeld 16 bestuderen.

Vanaf nu is het dus de bedoeling dat je alle css verdeeld over diverse stylesteets.

variabelen

Vlak onder de imports vind je in styles.css ook variabelen die in de :root worden gedefinieerd. Dit zijn instellingen die op meerdere plekken worden toegepast. Dus de achtergrond van de <main> wordt bijvoorbeeld ingesteld op beige. In de css - in dit geval layout.css. In deze stylesteel wordt de instelling als volgt toegepast:

body {
    ..
    background-color: var(--main-background);
}

Dus met heet sleutelwoord var kun je een variabele weer oproepen en zo vaak gebruiken als je wilt. Stel vanaf nu alle waarden die vaker dan één keer voorkomen in met een variabele.

reset.css

Een bijzondere stylesheet is reset.css. De meeste bekende browsers (Firefox, soms ook Internet Explorer, Opera en Chrome) kunnen onvoorspelbare resultaten genereren, afhankelijk van welke versie er is geïnstalleerd. Om dit zoveel mogelijk te reduceren gebruiken we een reset.css. Er bestaan verschillende versies van maar een van de beste reset is Eric Meyer’s Reset CSS. Je kunt deze in de link van reset.css zien.

5. Meerdere cards positioneren

We kunnen ook het aantal cards eenvoudig kopiëren en kijken hoe dit uitpakt. Dus we kopiëren een card telkens weer. Hieronder zie je er twee:

<section class="cards">
    <article class="card">
        <a href="#">
            <figure>
                <img src="images/who_are_you.png" alt=""/>
            </figure>
            <div class="card-content">
                <h2>Header</h2>
                <p>
                    Dit is de begintekst van de het item. De link wijst naar 
                    een vervolgtekst. 
                </p>
            </div><!-- .card-content -->
        </a>
    </article><!-- .card -->
    <article class="card">
        <a href="#">
            <figure>
                <img src="images/who_are_you.png" alt=""/>
            </figure>
            <div class="card-content">
                <h2>Header</h2>
                <p>
                    Dit is de begintekst van de het item. De link wijst naar 
                    een vervolgtekst. 
                </p>
            </div><!-- .card-content -->
        </a>
    </article><!-- .card -->
    <article class="card">
        <a href="#">
            <figure>
                <img src="images/who_are_you.png" alt=""/>
            </figure>
            <div class="card-content">
                <h2>Header</h2>
                <p>
                    Dit is de begintekst van de het item. De link wijst naar 
                    een vervolgtekst. 
                </p>
            </div><!-- .card-content -->
        </a>
    </article><!-- .card -->
..hieronder nog meer cards

We passen de stijlesheet cards.css als volgt aan:

.card {
    ..
    flex: 0 1 20%;
}

/*-------cards------------*/
.cards {
    display: flex;
    flex-wrap: wrap;
    justify-content:left;
    gap:1rem;
}

Het resultaat is te zien in voorbeeld 17. We zijn hier echter nog niet tevreden over omdat de pagina in een smallere versie zich niet goed gedraagt. We voeren daarom een media-query in waarin we dat corrigeren.

@media (max-width: 750px){
    .card {
        flex: 32%;
    }

}
@media (max-width: 900px){
    .card {
        flex: 48%;
    }
}

@media (max-width: 430px){
    .card {
        flex: 100%;
    }
}

In voorbeeld 18 gedraagt de pagina zich nu wel zoals we willen.

flex

De css-code flex is telegramstijl voor drie instellingen. Stel je stelt in flex: 0 1 20% dan stel je eigenlijk het volgende in:

flex-grow: 0;
flex-shrink: 1;
flex-basis: 20%;

Flex-grow betekent dat een element groeit ten opzichte van het vorige element. Flex-shrink betekent dat het krimpt ten opzichte van andere elementen. In de opdracht zullen we dit verder laten zien.

6. Een mooier en stabieler design

Over de layout zijn we eigenlijk nog niet tevreden. Het kan een stuk mooier. Met wat eenvoudige instellingen kun je de website een stuk mooier maken. We beginnen met het toevoegen van een extra knopje (button)

<article class="card">
    <a href="#">
        <figure>
            <img src="https://picsum.photos/500/300/?image=13" alt=""/>
        </figure>
        <div class="card-content">
            <h2>Header</h2>
            <p>
                Dit is de begintekst van de het item. De link wijst naar 
                een vervolgtekst. 
            </p>
            <button class="btn card_btn">Lees verder</button>
        </div><!-- .card-content -->
    </a>
</article><!-- .card -->

Op https://picsum.photos/ kun je dummy afbeeldingen vinden. Klik op de link om te kijken hoe het werkt. In je uiteindelijke project mag je niet met afbeeldingen werken die wijzen naar het internet. Deze dien je te downloaden en te plaatsen in het mapje img. Voor ontwikkeldoeleinden kunnen dummy afbeeldingen handig zijn evenals een dummy tekst.

We zullen nu de cards wat beter opmaken. We beginnen met de cards netjes te in het midden te positioneren. In dit geval doen we dit niet met de flexbox maar met margin. De maximale breedte stellen we in op 1200 pixels. De onderstaande code plaatsen we in layout.css, waar het thuis hoort.

main {
    margin:0 auto;
    max-width: 1200px;
    padding:1rem;
}

De button geven we de class btn en deze stellen we in de stylesheet card.css in met de volgende css-code.

.btn {
    color: #ffffff;
    padding: 0.8rem;
    font-size: 14px;
    text-transform: uppercase;
    border-radius: 4px;
    font-weight: 400;
    display: block;
    width: 100%;
    cursor: pointer;
    border: 1px solid rgba(255, 255, 255, 0.2);
    background: transparent;
}

Meest opvallende zaken in deze code zijn de text-transform (uppercase) en feit dat de achtergrond transparent is. In de hover geven we dan de achtergrond een licht, witte, doorschijnende kleur.

.btn:hover {
    background-color: rgba(255, 255, 255, 0.12);
}

De instelling 0.12 geeft aan in hoeverre de knop doorschijnend is. Met dit effect lijkt het alsof de achtergrond een beetje oplicht.

Het instellen van een gradiënt doet het ook altijd goed. Merk op dat we hier weer met een variabele werken die we hebben ingesteld in styles.css.

.card {
    background: linear-gradient(to bottom left, var(--background-card-begin) 40%, var(--background-card-end) 100%);
    flex: 0 1 32%;
    border-radius: 0.25rem;
    box-shadow: 0 20px 40px -14px rgba(0, 0, 0, 0.25);
}

In de code hebben we de cards ook een box-shadow en een border-radius gegeven waarbij de laatste instelling negatief is. In voorbeeld 19 is het resultaat te zien.

7. Webformulieren

Tot nu toe kende onze website geen interactiviteit. Dat wil zeggen dat er geen server is die verzoeken ontvangt, deze verwerkt en weer terug stuurt naar de cliënt. In deze cursus zullen we een basis leggen voor interactiviteit. Er zijn in basis drie manieren om interactiviteit te bewerkstelligen:

  1. Via een weblink die niet alleen de doelpagina maar ook variabelen bevat. Deze variabelen kunnen dan door de server worden verwerkt. Een voorbeeld van een link met een variabele is: https://duckduckgo.com/?q=wat+is+een+interactieve+link . De variabele heet q en in de q zit de zoekvraag. Klik er maar eens op. De achterligggende techniek zorgt dat jouw zoekvraag wordt uitgezet en je ziet meteen de resultaten.
  2. Via een webformulier.
  3. Overige manieren. Denk bijvoorbeeld aan het toestaan van je locatie waarna de website het lokale weerbericht kan tonen. Ook dat is een vorm van interactiviteit.

Optie 1 en 3 zullen we verder uitwerken in de cursus over interactiviteit. Deze zijn nu minder relevant. Optie 2 kunnen we wel wat verder uitwerken. Hieronder zie je een voorbeeld van een webformulier in de vorm van een inlogpagina. Zodra de gebruiker heeft geklikt op de blauwe knop Login worden de gebruikersnaam (piet) en wachtwoord (geheim) verstuurd naar de server. De server kan er verschillende dingen mee doen zoals de loginpoging opslaan in de database (de inlogtijd- en datum), een email versturen of een nieuwe webpagina maken en versturen naar de client.

https://images.computational.nl/galleries/html/2022-10-02_11-10-56.png

Alle drie opties tegelijk uitvoeren zou ook kunnen, afhankelijk van wat je bij de server instelt.

Een contactformulier

We zullen eens een poging gaan wagen om een contactformulier te maken. Hiervoor maken we in het mapje xhtml een nieuwe pagina genaamd contact.xhtml. Het  handigste is als je de index.xhtml kopieert en dan de <main> leegmaakt. De navbar moet wel aangepast worden (dit leggen we niet meer uit). In de <main> plaatsen we volgende code:

<main>
    <div class="centered">
        <form action="confirmation.xhtml" method="get" id="contact">
            <fieldset>
                <legend>Neem contact met ons op</legend>

                <label for="fullname">Uw naam:</label>
                <input type="text" name="fullname" id="fullname" />

                <label for="email">Email:</label>
                <input type="email" name="email" id="email"/>

                <input type="submit" id="submit" name="submit" value="Verzenden"/>
            </fieldset>
        </form>
    </div>
</main>

Hierover enige uitleg:

  1. Met de  coderegel <form action="confirmation.xhtml" method="get" id="contact">  begint het formulier. Het formulier wordt gemaakt met het element.<form>. Het attribuut action bepaalt welke bestand wordt uitgevoerd nadat het is verzonden. Vervolgens zien we het attribuut method="get". Hiermee bepaal je op welke manier het formulier wordt weggestuurd. Dit is een zogenaamd GET-verzoek. Alles wat weg wordt gestuurd gebeurt in de url zoals te zien is in het voorbeeld in het begin van de les. Een POST-verzoek is ook mogelijk: method="post". In dat geval wordt het formulier op een andere, meer onzichtbare, manier weggestuurd en kan er ook meer worden verstuurd zoals een bestand. Voor ons doel gebruiken we voorlopig het GET-verzoek. Vervolgens zie je de eigens id="contact". Dit is het id van het formulier en kan binnen de css worden gebruikt zoals je bij de CSS zult zien.
  2. Het <legend> element kun je zien als de kop van het formulier. Standaard produceert het een border.
  3. Hierna volgen enkele <inputs> (invoervelden) die telkens van een ander type zijn. Zo controleert de <input type="email" /> of er een emailadres wordt ingevoerd. De <input type="submit"/> zorgt ervoor dat het formulier kan worden verstuurd met behulp van een verzendknop. Merk op dat we alle inputs een id hebben gegeven.
  4. Tenslotte nog de labels. Dit zijn de kopjes boven de <input>. Met het attribuut for worden de labels aan de input gekoppeld. 
    <label for="fullname">Uw naam:</label>
    <input type="text" name="fullname" id="fullname" />
    
  5. Soms zie je ook wel eens dit: <input type="text" name="fullname" id="fullname" placeholder="uw naam" /> in plaats van een label. Dit is de verkeerde manier. In de placeholder hoort een voorbeeld van een in te voeren tekst te staan. In ons formulier is dit niet nodig.
  6. Merk op dat conformation.xhtml niet zoveel kan met de variabelen. Een andere bestand wat variabelen kan verwerken, zoals een java-bestand, zou dit wel kunnen omdat zo'n bestand kan communiceren met de server (eigenlijk met het framework wat door de server is ingeladen).

We kunnen nu ook de css koppelen. Hiervoor maken we een aparte css-file genaamd contactform.css. Deze importeren we in styles.css. De CSS hiervan is als volgt:

main {
    margin: 0 auto;
    max-width: 1000px;
    padding: 1rem;
}

.centered {
    display: block;
    justify-content: center;
    margin: 0 auto;
}

#contact fieldset {
    margin: 0 auto;
    padding: 1em 2em;
    border: solid 1px #ccc;
    border-radius: 6px;
    width: 50%;
    min-width: 200px;
}

#contact legend {
    font-size: 1.75em;
    padding: 0 .25em;
    color: #999;
}

label, .checks {
    display: block;
    padding-top: .5em;
    margin-top: 1em;
}

#contact input {
    padding: .5em;
    width:100%;
}

input#submit {
    margin-top: 2em;
    padding: .25em;
    display: block;
    border: 1px solid rgba(27, 31, 35, .15);
    border-radius: 6px;
    box-sizing: border-box;
    color: #fff;
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    line-height: 20px;
    padding: 6px 16px;
    background: linear-gradient(to bottom left, var(--background-card-begin) 40%, var(--background-card-end) 100%);
}

input#submit:hover {
    color: white;
    background:  var(--background-card-end);
}

@media (min-width: 750px){
    #contact input {
        width:60%;
    }
    #contact input#submit {
        width: 40%;
    }
}

We hebben in de navbar.css ook nog het volgende toegevoegd:

.active {
    color: white;
}

Door bijvoorbeeld in contact.xhtml in de navigatiebalk de class active toe te voegen kun je zien op welke pagina je bent. Verder maakten we ook de pagina conformation.xhtml. Dit leggen we niet al te nadrukkelijk meer uit. Je kunt zien hoe het werkt in voorbeeld 20 door op contact te klikken.

8. Een webpagina met twee of drie kolommen

We maken onze website zoveel mogelijk af door ook pagina's te maken die niet zijn gebaseerd op cards. We geven nu in een keer het voorbeeld (voorbeeld 20) en we zullen uitleggen hoe het werkt. Als eerste maakten we de html binnen het <main> element. Met dit element markeren we de content. Vervolgens zijn er drie kolomen in de eerste section.

De css stellen we in de page.css als volgt in waarbij we in styles.css een import maken.

.row {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}

.column {
    flex: 0 1 100% ;
}

div.row > div > div {
    padding: 1rem;
    height: auto;
}

div.row > div > p {
    padding: 1rem;
}

.orange-column {
    background-color: orange;
}

.blue-column {
    background-color: blue;
}

.green-column {
    background-color: green;
}

.double-column {
    flex-basis: 100%;
}

.nopadding {
    padding:0 !important;
}

.noborder {
    border: 0 !important;
}



@media screen and (min-width: 750px) {
    .column {
        flex: 1;
    }

    .double-column {
        flex: 2
    }

    .readmore {
        position:relative;
        margin-top:50px;
    }
}

Merk op dat we stijlen - classes -  hebben ingevoerd  die maar een ding doen zoals bijvoorbeeld .nopadding met instelling border: 0 !important; De naam van de stijl geeft aan wat het doet. Soms is dit erg handig.

--meer imports in styles.css
@import "css/page.css";

Uiteindelijk krijgen we onderstaande structuur waarbij we in het midden een plaatje hebben geplaatst (nu groen gemaakt).

https://images.computational.nl/galleries/html/2022-10-10_14-01-34.png

Merk op dat dit drie kolommen zijn. Ze gaan naast elkaar zweven door de instelling display: flex;. Dit is altijd de wikkel (wrapper) van de kolommen.  Met flex-direction: row; en flex-wrap: wrap; bepaal je hoé de kolommen (naast elkaar) gaan zweven. Vervolgens heeft iedere kolom (column) de instelling flex: 0 1 100% ;. Dat houdt in dat we iedere kolom 0 laten inkrimpen, 1 x laten groeien ten opzichte van elkaar (in dit geval dus gelijk) en 100% breedte heeft.

Stel nu dat we een dubbele kolom willen instellen met bijvoorbeeld een plaatje links en de tekst rechts. Qua structuur ziet dat er zo uit:

https://images.computational.nl/galleries/html/2022-10-10_14-17-36.png

We bereiken dit met de instelling:

double-column {
    flex: 2
}

Dit houdt in dat we in verkort schrijven flex-grow:2, dus de kolom groeit 2x de breedte van de volgende kolom. Alles is te zien in voorbeeld 21.

Nog een opmerking over de index.xhtml. De html hebben we een beetje veranderd:

<div class="card-content">
    <h2>Header</h2>
    <p>
        Dit is de begintekst van de het item. De link wijst naar 
            een vervolgtekst. 
    </p>
    <form action="xhtml/hobby.xhtml" method="get" class="readmore">
        <button class="btn">Lees verder</button>
    </form>

</div><!-- .card-content -->

Merk op dat we nu de button in een form hebben geplaatst waarbij we de action laten wijzen naar de pagina die we willen zien.

9. Het maken van een website - eindopdracht

De website is een website over jezelf. Je laat zien wie je bent, wat je hobby's zien, enkele foto's etc. Als je het fijner vindt om iemand anders te nemen dan jezelf dan mag dat ook zoals bijvoorbeeld een bekende Nederlander. Aan je website worden de volgende eisen gesteld.

  • Een menu zoals is uitgelegd in deel 2 (20 punten).
  • Je website heeft de juiste structuur, dus aparte mapjes maken voor css, html en images. Ook alle linkjes in het menu werken. Cards mogen naar dezelfde pagina linken als de linkjes in het menu. De website heeft minimaal 5 pagina's (20 punten).
  • De homepage heeft minimaal vijf cards zoals uitgeleg is in deel 3 die niet persé allemaal hoeven te werken (15 punten).
  • De website heeft een aparte stylesheet genaamd styles.css met een import naar andere stylesheets die staan in het mapje css. De complexiteit van de stylesheet wordt beoordeeld (20 punten)
  • Het gebruiken van een framework evenals het gebruik van Javascript is verboden. De uitzondering hierop is Font Awesome en Google Fonts.
puntenverdeling (als een onderdeel afwezig is dan scoor je daarmee geen punten)
5 10 15 20 maximaal te behalen
Er is een menu maar daarmee is alles gezegd. Het menu is grotendeels ingesteld zoals is uitgelegd in deel 2. Alle linkjes wijzen naar een werkende pagina. Zoals bij 15 maar het menu kent ook een submenu. Dit hoeft niet persé te verwijzen naar pagina's (niet uitgelegd in de lessen). 15
Alle files staan in het juiste mapje. 5
2 tot 3 linkjes werken niet Vrijwel alle linkjes werken 10
De homepage heeft 3 cards of meer. Responsive werkt matig of niet. De homepage heeft minimaal 5 werkende cards en deze zijn responsive. 10
Er zijn 2 pagina's zonder cards zoals uitgelegd in les 8 maar niet op de juiste manier gepositioneerd. Er zijn 2 pagina's zoals uitgelegd in les 8. 10
De style is aanwezig maar niet op de juiste manier toegepast Er zijn een of meerdere stylesheets maar deze zijn niet onderverdeeld Stylesheets, inclusief variabelen zijn op de juiste manier toegepast. 15
Het design van de website is matig. Het design van de website is voldoende. Het design van de website is goed en stabiel. Uitmuntend design. 20
De website heeft een contact- of inlogformulier. 10
Er is te zien op welke pagina de gebruiker is door class="active" te gebruiken. 5
totaal 100

_____