Pages

mercredi 18 mai 2016

Flexbox, la solution pour disposer sans problème des éléments HTML dans une page

Etes vous plus Material DesignBoostrapPure CSSFundation ? Pourquoi passez-vous par un framework CSS ?

Personnelement au début je pensais qu’ils allaient me faire gagner du temps mais au final je suis toujours obligé d’apprendre de nouvelles classes de style et je me dis que si j’avais investi autant de temps dans l’apprentissage de CSS j’aurai perdu moins de temps. Aujourd’hui nous pouvons faire beaucoup plus simple avec de simple notions basiques de ce langage qui est très puissant.

En CSS le plus gros problème reste la disposition des éléments les uns par rapport aux autres. Vous devez connaître quelques astuces pour arriver à vos fins. C’est pourquoi la grosse majorité des développeurs (et moi le premier) se sont orientés vers ces frameworks tout fait et les différentes solutions de grilles mises à disposition.

Certes ils vous amènent également un style général, un visuel à votre site. Mais à mon sens ils sont beaucoup trop lourds. Il existe différents outils pour vous aider à packager au mieux votre application pour le web et les rendre moins lourds. Ce n’est pas le sujet de cet article mais si vous voulez des pistes je vous conseille le talk de Addy Osmany CSS Performance.




Sur des besoins simples je me suis rendu compte que la première chose que je faisais était de charger un framework CSS. Mes besoins sont souvent très limités... Est ce qu'utiliser  5% d’un Bootstrap pour aligner correctement des éléments est  la meilleure solution ?  Je ne pense pas

Les flexbox 

Nous allons voir dans cet article comment nous pouvons disposer simplement des éléments dans une page web avec quelques propriétés CSS. Et pour celà je vais m’appuyer sur les flexbox. Si vous regardez les navigateurs supportant cette feature, je pense que vous pouvez maintenant l’utiliser dans la plupart des cas.



Mon but est de montrer comment répondre à 2 problématiques

  • Mettre en place un layout avec un header et un footer fixes, et un corps de page qui prend le reste de l’espace et permet de scroller si besoin
  • Disposer des éléments sous forme de grille avec potentiellement des zones plus grandes que d’autres

Les flexbox (flexible box) permettent via quelques règles de disposer des élements dans un élément parent (position, alignment, espacement…). Le but de cette spécification est d’essayer d’optimiser l’espace disponible dans l’élément parent. Nous pouvons définir via quelques propriétés le comportement lors d’un redimensionnement (extension des box ou réduction).

Quand on utilise les flexbox nous n’avons pas de notion de droite/gauche, haut/bas. Nous pouvons définir une disposition selon un axe : ligne ou colonne.

Pour disposer les éléments sous forme de grille, une autre spécification, Grid est en cours d’adoption mais elle loin d’être utilisable sous tous les devices. C’est pourquoi j’utiliserai aussi les flexbox pour apporter une réponse à ce problème



Il est temps de prendre un exemple. Nous allons construire cette page



Le code de ma page est assez simple.

<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Exemple de flexbox</title>
    <link rel="stylesheet" href="style.css">
    <link rel="icon" href="favicon.ico" type="image/x-icon">
</head>

<body>
    <header>
        <a href="#">Link 1 </a>
        <a href="#">Link 2 </a>
        <a href="#">Link 3 </a>
    </header>
    <main>
        <p class="logo">
            <img src="assets/img/logo_1500.png" class="img-responsive">
        </p>

        <grid>
            <div id="extended">Column 1</div>
            <div>Column 2</div>
            <div>Column 3</div>
            <div>Column 4</div>
        </grid>
    </main>
    <footer>
        All right reserved - @2016 Guillaume EHRET
    </footer>
</body>
</html>

Pour le moment le rendu est assez basique

Pas très responsive tout ça…. Nous allons compléter au fur et à mesure notre feuille de style

Définir un layout principal

Pour commencer nous devons dire que notre page occupera 100% de l’espace. Vous pouvez le faire en définissant le code ci dessous (on le déclare à la fois pour la balise html et body car tous les navigateurs ne gèrent pas cette définitition de la même manière)

html, body {
    min-height: 100vh;
    max-height: 100vh;
    margin: 0;
}


Nous indiquons que notre espace principal est une flexbox via l’attribut display. Nous définissons aussi la direction de l’axe via la propriété flex-direction (la propriété par défaut est en ligne mais là nous voulons une orientation en colonne)

display: flex;
flex-direction: column;

Nous pouvons également indiquer comment les élements sont affichés

  • Au niveau de notre axe x via la propriété justify-content (flex-start [défaut], flex-end, center
  • Au niveau de l’axe y via la proprité align-items
  • Au niveau du contenu des éléments, propriété align-content

Si vous voulez tester les différentes possibilités je vous conseille le site http://flexbox.help/ ou http://codepen.io/osublake/pen/dMLQJr/

Dans notre header on veut afficher les élements à droite de l’axe x et au milieu de l’axe y. Nous commençons par dire que notre header est elle même une flexbox

header {
    display: flex;
    justify-content: flex-end;
    align-items: center;
}


Les 3 principales propriétés pour les éléments d’une flexbox sont

  • flex-grow : on indique comment un élément occupe l’espace en définissant un poids (par défaut 0). Si tous les éléments ont le même poids l’espace est découpé équitablement
  • flex-shrink : indique si un élément peut se réduire quand la place vient à manquer. Par défaut la valeur est 1 pour indiquer que oui.
  • flex-basis : permet de définir la taille par défaut d’un élément avant que les 2 autres propriétés soient appliquées avant de répartir l’espace restant

Ces 3 propriétés peuvent être jumelées dans la proprité flex. Tous les élements ont d’une flexbox ont par défaut une propriété flex : 0 1 auto

Maintenant que nous savons tout ça nous pouvons indiquer comment l’espace se répartit entre le header, la zone main et le footer. Le header et le footer ne doivent pas bouger en cas de redimensionnement et nous pouvons imposer une taille de 64px à notre header

header {
    flex: 0 0 64px;
}
main {
    flex: 1 1 auto;
}
footer {
    flex: 0 1;
}

Définir une grille

Pour mes besoins de grille nous avons déjà tout vu plus haut et au final notre code CSS ressemblera à ça

grid {
    display: flex;
}

grid > div {
    flex: 1;
    margin: 10px;
    padding: 1em;
    text-align: center;
}

Notre page commence à prendre forme

Le code final

Les éléments sont disposés correctement mais notre page n’est pas très jolie. On peut rajouter rapidement quelques propriétés pour embellir notre page et la rendre plus harmonieuse

  • Une font un peu plus sympa
  • Des couleurs pour distinguer le footer et le header
  • Une ombre sur le header pour montrer qu’il est surélevé et fixe
  • Une scrollbar dans la partie centrale
  • Rendre l’image responsive

Voila ce que donne le code final

html, body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    max-height: 100vh;
    margin: 0;
}

body{
    font-family: Arial;
}

header {
    flex: 0 0 64px;
    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
    background-color: #0288d1;
    display: flex;
    justify-content: flex-end;
    align-items: center;
}

header > a {
    color: white;
    text-decoration: none;
    text-transform: uppercase;
    padding: 0 1em;
}

main {
    flex: 1 1 auto;
    overflow-x: hidden;
    overflow-y: scroll;
}

footer {
    flex: 0 1;
    background-color: #424242;
    color: white;
    padding: 1em;
}

grid {
    display: flex;
}

grid > div {
    flex: 1;
    background-color: #cccccc;
    margin: 10px;
    border-radius: 4px;
    padding: 1em;
    text-align: center;
}

#extended {
    flex: 2;
}

.logo{
    text-align: center;
}
img{
    max-width: 100%;
    height: auto;
}

Les flexbox permettent vraiment de nous simplifier la vie lorsque l’on veut disposer nos élements les uns par rapport aux autres. Sur le sujet je vous conseille le site css-tricks ou la vidéo dans laquelle Hubert Sablonnière explique comment marche les flexbox à Devoxx France 2016.

Vous pouvez retrouver les sources sur Github

Aucun commentaire:

Enregistrer un commentaire

Remarque : Seul un membre de ce blog est autorisé à enregistrer un commentaire.