La propriété CSS width est certainement celle qui porte le plus mal son nom.
En effet, elle représente la taille de la composante de contenu uniquement, pas largeur de l’élément. A vrai dire, l’appellation content-width
lui conviendrait parfaitement et serait bien moins source de problèmes, mais voilà, elle s’appelle bel et bien width
, et c’est ça le drame.
—
Il est dangereux de croire que width
correspond à la largeur de l’élément puisque dès que des marges internes (paddings
) ou bordures (border
) y sont ajoutées, la taille totale de l’élément ne correspond plus du tout à width
.
Et c’est d’autant plus problématique que l’on voit pulluler partout des width: 100%
… ce qui crée potentiellement des éléments qui déborderont joyeusement de leur parent dès lors que le moindre padding
ou la moindre bordure seront appliqués.
width: 100%
c’est le mal !
C’est tout.
Dans la grande majorité des cas, on peut aisément se passer de width: 100%
- Vos éléments sont des blocks (div, p, h1, ul, etc.) ? Parfait, ils occupent déjà par défaut toute la largeur disponible, ne les ennuyez pas à préciser
width
, - Vos éléments sont en
position absolute
oufixed
et doivent occuper toute la largeur ? Pas de souci, appliquez-leur plutôt unleft
etright
à zéro, - Vous avez un
max-width: 100%
sur vos images (et autres) pour les rendre “responsive” sur petits écrans ? Tout va bien, pensez àbox-sizing: border-box
, - Pour les champs de formulaires ? Même solution :
box-sizing: border-box
- Votre élément est un tableau HTML ?
width 100%
ne posera aucun problème car par défaut l’élémenttable
est déjà enbox-sizing: border-box
donc les paddings et borders s’affichent à l’intérieur, - Vous souhaitez “écraser” une valeur de
width
en redonnant à votre élément toute la largeur disponible ? Plutôt que la valeur100%
, pensez à la valeur par défaut dewidth
, c’est à direauto
.
Voilà, ce n’est pas si dur de se passer de width: 100%
, non ? 😉
Bonjour,
Je suis d’accord sur la plupart des points, par contre est-il si judicieux de préconiser box-sizing à toutes les sauces ?
Sauf erreur, il ne réagit pas de la même manière selon le navigateur, pire selon le navigateur et sa version, et notre ami IE a bien du mal à s’en dépêtrer…
Sans parler d’Android (toutes versions confondues) qui calcule de travers les dimensions et ne rend pas la même chose…
Pour box-sizing, la réponse est simple : dans notre environnement de production, je n’imagine même pas que l’on puisse encore ne pas l’utiliser. Nous avons tout simplement laissé tomber IE7 l’an passé pour pouvoir utiliser massivement box-sizing.
Il me semble aujourd’hui que tous les frameworks CSS les plus utilisés (et éprouvés) au monde sont basés sur box-sizing. Nous n’avons pas rencontré de problèmes particuliers avec cette propriété, ni de réactions différentes de navigateurs, dans aucun de nos projets depuis 2 ans. As-tu des infos plus précises sur ce sujet ?
Bonjour.
J’ai un div à 33% de largeur qui doit contenir une image. Cette image doit impérativement le remplir en largeur. Je la met en display: block, ça ne suffit pas. Je lui ajoute le box-sizing: border-box, ça ne suffit pas non plus. Alors je lui met width: 100% et là, ça marche… Tout compte fait, width: 100% me parait pas si mal… Je précise que je fais mes tests sous Safari iOS.
box-sizing n’a rien à voir avec ton problème : il ne va pas transformer ton image pour lui accorder toute la largeur de son parent.
Certaines éléments très spécifiques tels que les images ou les inputs, où la largeur par défaut est intrinsèque et où display: block ne fonctionne pas nécessiteront parfois du width 100% … qui deviendra malheureusement problématique dès lors que ces éléments (img, input) auront une bordure ou un padding
(sauf s’ils ont un box-sizing: border-box)
Pour mieux comprendre, il n’y a rien de mieux qu’un petit exemple
Sans
box-sizing: border-box
:– un padding à 10px
– une bordure à 10px
– width à 200px
—> le contenu (du texte par exmple) occupera 200px et la balise fera en faite 240px (pas ce qu’on veut…)
Avec
box-sizing: border-box
:– un padding à 10px
– une bordure à 10px
– width à 200px
—> le contenu (du texte par exmple) occupera 160px et la balise cette fois fera bien 200px comme voulu.
Si je comprend bien, si on a ni padding, ni bordure, le box-sizing sert à rien?
Exactement.
Mais cela devient compliqué à gérer d’avoir « des fois » du box-sizing et « des fois » pas.
Et pour le cas de flexbox, qu’en est-il ?
Flexbox ne change pas grand chose à la donne, en tout cas pour width :
– width: 100% + padding fera toujours plus de 100%, mais si la valeur de flex-shrink est laissée à « 1 » (valeur par défaut), alors l’élément aura l’obligation de rétrécir. Sinon, il débordera.
– idem avec flex-basis: 100% d’ailleurs
Et pour le cas de flexbox, qu’en est-il ? On peut éviter le width: 100%, ou c’est comme pour les input ? Je trouve ça dommage que les éléments en display: flex; ne prennent pas la largeur disponible par défaut.