Publié le 28 février 2017

Comment réussir votre centrage vertical ?

Intéressant cet article ?

[Total : 7    Moyenne : 3.7/5]

Amis intégrateurs, votre graphiste a récidivé ? Il a encore sorti une maquette qui allie Flat Design et Skeuomorphisme (performance !) et vous demande de centrer les éléments verticalement ? Et vous avez beau placer du vertical-align : middle comme vous le recommande un développeur d’IE6, rien n’y fait…

Pour la paix des ménages équipes web, nous avons demandé à Vincent, développeur front-end chez nous, de venir à la rescousse !

Avant tout, sachez jeunes fonceurs (répétez-le 10 fois sans écorcher un mot pour voir) que vous n’êtes pas seuls dans cette situation ! Voici un tutoriel pour vous aider à relever les défis posés par votre maudit graphiste préféré.

3 façons de réaliser un centrage vertical

1er défi du graphiste (qu’il se cogne l’orteil contre un meuble !)

 Découvrons ce que ce méchant bonhomme nous a produit.

Centrage-vertical_blog-JETPULP-defi-01-00

Alors, plusieurs choses à dire :

  1. Mon dieu mais ce graphiste est vraiment très mauvais !
  2. Ce singe aime vraiment les bananes !
  3. Effectivement, c’est centré !

Posons notre HTML pour commencer, code sommaire mais efficace, vous devriez obtenir ceci :

See the Pen blog #1 by JETPULP (@jetpulp) on CodePen.0

Humm… continuons avec le css :

See the Pen blog #2 by JETPULP (@jetpulp) on CodePen.0

Waouh ! On y est presque ! Gardez ce code de côté, nous n’y toucherons plus.

Maintenant le centrage…

À partir d’un truc sommaire comme ça, nous avons plusieurs choix :

Le foirage absolu

Beaucoup de gens vous dirons comme Jean-Kevin du 69 : « Bah c’est tout bête, tu mets le biniou en absolute avec un top 50 %, tu compenses la hauteur avec un margin négatif et c’est plié ! »

Suivons donc la solution de Jean-Kevin :

See the Pen blog #3 by JETPULP (@jetpulp) on http://codepen.io“>CodePen.0

Et là, vous vous dites : « WOOHOO ! C’est gagné ! C’est parfaitement centré! Merci ô merci Jean-Kev’ ! »

STOP !

Minute papillon ! Vous sautez de joie ? Oui mais voilà, vous avez un trombinoscope à faire et le texte n’est pas toujours identique ! Vous allez devoir générer des clauses pour rajouter des classes pour rectifier et ainsi de suite !

Exemple, considérons le cas suivant : le deuxième élément de la liste a un intitulé différent.

See the Pen blog #4 by JETPULP (@jetpulp) on CodePen.0

Ah ! Vous voyez ? Et là, qu’est-ce qu’il dit Jean-Kevin ? Et ben il ne dit rien…

Que s’est-il passé ? Quand nous faisons un top:50 %, nous fixons le bord haut de l’élément à 50 % de son conteneur mais nous devons compenser de la moitié de sa hauteur pour que celui-ci soit centré !

Mais en fait l’élément “.banana” n’a pas une hauteur fixe, ce qui arrive fréquemment, donc notre margin négative ne correspond plus ! Vous entendez Jean-Kevin ? « Je sais, je sais, je sais ! On va mettre un transform et comme ça ça va marcher ! » Alors écoutons Jean-Kevin et posons un transform à la place du margin-top négatif :

See the Pen blog #5 by JETPULP (@jetpulp) on http://codepen.io“>CodePen.0

Bien joué Jean-Kevin ! Mais il manque quelque chose… « Can I use » ça vous parle ? C’est un site qui référence toutes les compatibilités navigateurs des propriétés CSS. Et CanIUse nous dit que pour maximiser la compatibilité, nous avons besoin de préfixer la propriété.

Donc :

See the Pen blog #6 by JETPULP (@jetpulp) on CodePen.0

Bon maintenant démontons tout…

Mauvaise nouvelle !

Un élément en absolu n’a plus de taille pour son parent, imaginez que l’image soit plus petite que le texte, l’élément parent prend la hauteur des éléments en static ou relative, donc celle de l’image dans le cas présent et ça déborde ! Bah voilà, c’était couru d’avance Jean-Kevin !

See the Pen blog #7 by JETPULP (@jetpulp) on http://codepen.io“>CodePen.0

Bon, essayons autre chose :

Le combo inline-block / vertical-align

Nous avons évoqué plus haut la propriété «vertical-align:center ». Elle fait écho à l’attribut de tableau valign=’center’ qu’on trouvait sur les balises td ou tr. Or celle-ci est capricieuse, elle obéit aux règles suivantes :

  • seuls certains éléments en display l’appliquent :
    • display : inline ;
    • display:inline-block ;
    • display : table-cell ;
    • display : inline-flex ;
    • display : inline-box ;
    • display : inline-grid ;
    • display : inline-table ;
  •  Le centrage vertical s’applique en fonction du line-height du parent.

 Du coup pour pouvoir centrer un élément dans la hauteur, il faut procéder comme suit (commentaires dans le code) :

See the Pen blog #8 by JETPULP (@jetpulp) on CodePen.0

Et là, magie ! On peut ajouter tout un tas d’éléments dans “.banana” tout sera toujours centré.

D’ailleurs il est préférable de changer le span class=’banana’ par une div class=’banana’ comme ça nous pouvons ajouter des éléments comme on le souhaite sans écorcher les yeux des autres développeurs front-end qui passeront derrière vous.

See the Pen blog #9 by JETPULP (@jetpulp) on http://codepen.io“>CodePen.0

Bon maintenant démontons tout…

Mauvaise nouvelle !

Il y a plusieurs problèmes :

  • Par exemple si le parent est moins large que les 2 éléments, ceux-ci passent à la ligne (c’est normal, ça agit comme un inline),
  • en plus, le inline-block génère un espace plus ou moins grand entre les éléments qui varie selon les navigateurs. Il existe plusieurs hacks pour pallier à ça, mais là n’est pas la question,
  • enfin nous sommes obligés de fixer la hauteur de l’élément, et là ça embête vraiment…. Cette méthode est néanmoins pratique pour centre les éléments dans une div qui fait la hauteur de l’écran grâce aux vh (le line-height n’accepte pas les pourcentages [ %], mais accepte les vh [ ex: 100vh correspond à toute la hauteur de l’écran] ).

Petit code utile avec les vh par exemple pour une popin :

Centrage-vertical_blog-JETPULP_code-popin

Revenons à nos moutons et essayons la troisième solution.

Le méga combo table / vertical-align

Comme dit plus haut, le vertical-align: middle; est à l’origine fait pour des tableaux, nous allons donc simuler un tableau grâce aux displays “table” et “table-cell”. Changeons un peu la structure pour l’adapter à nos besoins.

Regardez bien la partie html du code ! Notez que l’on utilise une seule classe “.cell” pour ne pas se mélanger.

See the Pen blog 10 by JETPULP (@jetpulp) on CodePen.0

Ouah ! Amazing! On y est !
Quels que soient les contenus des 2 cellules, le parent va s’agrandir pour prendre la hauteur du composant le plus grand, et en plus, le contenu de chaque cellule est contraint.

Regardons ce qui se passe quand les contenus sont trop petits :

See the Pen blog 11 by JETPULP (@jetpulp) on CodePen.0

Ca marche toujours !

3 méthodes oui, mais laquelle choisir ?

2e défi du graphiste (qu’il trouve toujours au moins une arête dans son poisson !)

Centrage-vertical_blog-JETPULP_defi-02-00

Oh le filou ! 2 colonnes avec un centrage vertical !

Déjà voici l’html, on va contraindre le tout dans un conteneur et fixer sa taille. Bon, utilisons le float-left; pour voir ce que ça dit.

See the Pen blog 12 by JETPULP (@jetpulp) on http://codepen.io“>CodePen.0

Hm… Pas terrible, les parents ne sont pas de la même hauteur, du coup c’est moche. Tentons 2 approches, une purement CSS (conseillée) et une JavaScript.

css grâce au table-row

Étant donné que le display: table; permet de générer des semblant de tableaux, nous pouvons contraindre certaines lignes grâce au display: table-row; équivalent aux td.

Nous allons donc devoir modifier notre html pour créer ces fameuses colonnes. Nous ajoutons des div class=’table-row’ qui porteront la propriété CSS éponyme :

See the Pen blog 13 by JETPULP (@jetpulp) on http://codepen.io“>CodePen.0

Ah ce n’est pas mal, mais les traits ne sont pas en face… Il suffit alors de déplacer ces derniers du “.parent” vers les cellules juste au-dessus (.main-cell) :

See the Pen blog 14 by JETPULP (@jetpulp) on CodePen.0

On y est presque !

Le problème, c’est que pour espacer les cellules, nous ne pouvons pas utiliser de margin, seuls les paddings agissent, ce qui fait que les borders sont placés après. Nous allons donc gérer les bordures autrement, via les pseudo-éléments :

See the Pen blog 15 by JETPULP (@jetpulp) on CodePen.0

Là votre graphiste est content, vous pouvez profiter qu’il regarde votre écran et donc qu’il vous tourne le dos pour lui piquer un cheveu histoire de fignoler votre poupée vaudou (s’il est chauve un high kick fera l’affaire).

L’approche Javascript

Une autre approche consiste à utiliser du JavaScript. L’inconvénient de cette méthode, c’est le responsive : vous devrez créer des clauses en fonction de votre taille d’écran pour retirer ce que vous ajouterez. Nous allons partir du principe que vous n’avez qu’une version desktop à faire et que vous utilisez jQuery.

Nous allons donc parcourir le DOM à la recherche d’éléments face à face nécessitant un resize en hauteur, nous fixerons alors la hauteur à celle de l’élément le plus haut. Pour ce faire, nous allons repasser sur la structure en inline-block. Voici donc l’html et le css de départ.

Prêtez bien attention, entre la div “.monkey-container” et “.banana”  nous avons placé des commentaires qui permettent d’ignorer les espaces et sauts de ligne pour que le display: inline-block; ne génère pas d’espace entre ces 2 div. Sans ça, les 2 div à 50% prendraient plus de 100% et donc passeraient à la ligne. Oui, c’est pénible mais c’est comme ça avec l’inline-block.

See the Pen blog 16 by JETPULP (@jetpulp) on http://codepen.io“>CodePen.0

Vous vous souvenez, avec le inline-block nous devions avoir une height fixe, nous allons la placer en Javascript (on utilise jQuery parce que ça va plus vite, n’oubliez pas de l’importer) :

See the Pen blog 17 by JETPULP (@jetpulp) on CodePen.0

Et voilà, maintenant vous êtes prêts à voler de vos propres ailes, petits développeurs front-end. Vous pouvez briller en société en disant que le centrage vertical, c’est easy, finger in the nose!

Un nouveau défi de graphiste appelle notre téméraire Vincent (une sombre histoire de formes mi-triangulaires mi-sphériques sur de l’AMP) mais vous pouvez lui poser vos questions en commentaires !

Vincent

comment-fonctionne-responsive-webdesign_blog-agence-jetpulp
comment-fonctionne-responsive-webdesign_blog-agence-jetpulp
comment-fonctionne-responsive-webdesign_blog-agence-jetpulp
comment-fonctionne-responsive-webdesign_blog-agence-jetpulp
comment-fonctionne-responsive-webdesign_blog-agence-jetpulp
1 Commentaires
  1. Jul
    Jul dit :

    Merci pour l’article.

    Il faut bien sûr lire : ‘au display: table-row; équivalent aux tr’ et non au td…

    A plus (ure de banane)

    Jul.

    Répondre
Répondre
Se joindre à la discussion ?
Vous êtes libre de contribuer !
Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *