Dans la même veine que le « Quiz CSS » posté il y a maintenant quelques années par Thierry Koblentz, je vous propose un Quiz Flexbox.
La question est : parmi l’ensemble des déclarations suivantes, lesquelles n’ont pas d’effet ?
(dans le sens « lesquelles ne s’appliquent pas ou bien reproduisent inutilement la valeur par défaut »).
Notes :
- la page ne contient que ces styles et rien d’autre, et les éléments ciblés existent dans le DOM (edit: et ne sont pas des tableaux).
- le code doit pouvoir fonctionner avec un ou plusieurs flex-items.
- si une propriété s’applique, si elle impacte le comportement, il faut la conserver.
- le code est à tester sur un navigateur moderne ne présentant pas de bug majeur sur Flexbox (donc pas IE10 et IE11)
- ne cherchez pas trop sur Google et ne testez pas tout de suite le code sur une vraie page, sinon il n’y a plus de plaisir 😉
.flex-container { display: flex; flex-flow: column nowrap; align-items: space-between; flex-direction: row; } .flex-item { flex: 1; display: block; align-content: center; flex-shrink: 1; float: left; clear: both; z-index: -1; bottom: 1em; vertical-align: top; width: 250px; height: 250px; }
Laissez-moi vos réponses par commentaires.
Je donne le corrigé explicatif très prochainement.
Correction et explications.
Voici donc le verdict. Je préviens qu’il y avait forcément pas mal de pièges et que j’avoue que l’énoncé n’était pas toujours très clair. L’essentiel demeurait de participer et de découvrir des choses méconnues.
La réponse la plus proche, munie des explications les plus complètes vient de Loïc Giraudel, bravo à lui !
Sur le .flex-container :
display: flex;
(à conserver)
c’est le postuat de départ sans lequel rien ne s’affiche correctement. On garde forcément.flex-flow: column nowrap;
(inutile)
column
sera écrasé plus bas parflex-direction
etnowrap
est la valeur par défaut.align-items: space-between
(inutile)
ne s’appliquera jamais… puisquespace-between
n’est pas une valeur autorisée pouralign-items
(très peu y ont prêté attention).flex-direction: row;
(inutile)
row
est la valeur par défaut, bref on retourne à l’état initial d’un flex-container.
Sur le .flex-item :
flex: 1;
(à conserver)
permet au flex-item d’être fluide, correspond àflex: 1 1 0;
(la valeur par défaut étantflex: initial;
, soitflex: 0 1 auto;
)display: block;
(inutile)
presque aucune valeur dedisplay
n’est prise en compte sur un flex-item (saufnone
etflex
, et sauf bugs sur IE10-IE11).align-content: center;
(inutile)
cette propriété ne s’applique que sur un flex-container.flex-shrink: 1;
(inutile)
il s’agit de la valeur par défaut deflex-shrink
et elle n’entre pas en contradiction avec la déclaration précédenteflex: 1;
, elle est donc inutile.float: left;
(inutile)
la propriétéfloat
ne s’applique pas à un flex-item.clear: both;
(inutile)
la propriétéclear
ne s’applique pas à un flex-item.z-index: -1;
(à conserver !)
c’est assez inattendu, mais un flex-item crée un « stacking context » et la propriétéz-index
s’y applique. Il est donc nécessaire de conserver cette déclaration car elle peut modifier le comportement de l’élément et de son environnement (dans le code initial, j’avaisz-index:0;
mais l’argument reste le même).bottom: 1em;
(inutile)
la propriétébottom
ne s’applique qu’aux éléments positionnés, or un flex-item ne l’est pas par défaut, elle est donc ignorée ici.vertical-align: top;
(inutile)
la propriétévertical-align
ne s’applique pas à un flex-item.width
(inutile)
est écrasé parflex-basis: 0
, prioritaire, et contenu dans la déclarationflex: 1
(qui pour rappel vautflex: 1 1 0;
)height
n’est pas écrasé parflex-basis: 0
car ce dernier n’agit que sur l’axe principal (row
ici), donc cette propriété s’applique.
Au final, voici ce qu’on conserve :
.flex-container { display: flex; } .flex-item { flex: 1; z-index: -1; height: 250px; }
Merci à tous ceux qui ont joué, encore désolé si l’énoncé n’était pas toujours très clair (entre les propriétés qui ne s’appliquent pas, celles qui ne servent à rien), et j’espère que vous y avez appris des trucs !
Bonjour,
Allez, je me lance :
– Dans .flex-container pas de flex-direction: row car valeur contraire à flex-flow.
– Dans .flex-item pas de display : block car nous sommes dans le mode flex .
– align-content est pour le parent .flex-container donc pas nécessaire ici…
– flex-shrink: 1; est une répétition de flex: 1 (vaut 1 1 0%)
– Nous sommes dans le cas d’item flex donc ‘float’, ‘clear’, ‘vertical-align’, ‘z-index’ n’auront pas d’effet
Hello,
J’essaye aussi!
flex-direction redondant avec flex-flow
display: block inutile puisque flex
align-content ne marche que sur les containers
float et clear inutiles puisque flex
z-index et bottom inutiles puisque positionnement static (par défaut)
width pourrait être géré avec la propriété shorthand flex
Hello,
Allez tentons, mais je sens que je vais dire de grosses conneries. En fait, j’ai toujours du mal avec ce genre de quiz, parce que si on part du postulat
display:flex
ou si on l’enlève, ce n’est pas pareil…Voilà mon retour:
Bon je sais maintenant qu’il y a d’autres erreurs, mais
flex-direction: row;
c’est un oubli, la déclaration est bien entendu inutile (cf. commentaireflex-flow
)Mais en lisant les autres commentaires, je vois que je ne suis pas le seul à faire des postulats, qui influent sur nos réponses. 🙂
Hey tu spoiles !
ok, je me lance. Je pars du principe qu’il y a plus d’un element « flex-item » parce que si il n’y en avait qu’un on pourrait faire au minimum pour créer une simple boite qui fait 250px de haut et prend toute la largeur de son parent.
Les déclarations qui me paraissent superflues pour « flex-item »: display, align-content, flex-shrink (because of width), float, clear, z-index, bottom, vertical-align, and width (because of flex:1).
Celles pour « flex-container »: align-items, mais après ça je ne suis pas sûr pour flex-flow and flex-direction. C’est la cascade qui décide?
Je me rends compte que j’assume un truc qui n’est pas nécessairement vrai (?). Si il y a d’autres elements, le fait d’enlever la déclaration « z-index » changera the stacking context. Donc pour celle-ci, « ça dépend » 😉
S’il est risqué de supprimer une propriété, alors elle doit rester 😉
Héhé, réponse demain ou après-demain ? 😉
PS : pour « flex-shrink (because of width) », en fait flex-shrink est prioritaire sur width, non l’inverse
Hehe, ça montre combien je me sers de flexbox 😉
Hello,
alors sans avoir lu les commentaires précédents et en partant du postulat que le rendu visuel doit être identique au code initial, je garderai :
.flex-container {
display: flex;
}
.flex-item {
flex: 1;
height: 250px;
}
Pour le flex-container :
– flex-direction: row écrase flex-flow: column nowrap;
– flex-wrap est par défaut à nowrap;
– align-items: space-between; ne servira à rien étant donné qu’il n’y aura qu’une seule ligne sur l’axe principal. (pas de retour à la ligne)
Pour les flex-item :
– display: block; ne servira visuellement à rien même si par défaut son modèle est de type inline-block.
– align-content: center; ne s’applique que pour du Multi-lignes.
– flex-shrink: 1; est la valeur par défaut d’un flex item (flex: 0 1 auto;)
– float: left; et clear: both; ne s’appliquent pas pour des flex items.
– z-index: 1; donc la ça dépend, je l’ai enlevé car dans l’exemple ça ne changera rien visuellement mais j’ai appris ce matin sur css-tricks que par défaut un flex item se comporte comme un inline-block en position relative; Il possède un contexte d’empilement. z-index peut donc être applicable à un flex item sans posséder de position relative.
– bottom: 0; ne servira à rien non plus pour un élément relatif. (l’Élément restera à la même place)
– width: 250px; sera écrasé par le flex: 1;
Voila, en espérant ne pas avoir raconter trop de bêtises 🙂
Je viens de remplacer bottom: 0; par bottom: 1em; (désolé)
Ah c’est de la triche ! Du coup je garde le bottom: 1em ^^
Je ne pense pas que « son modèle est de type inline-block » mais plutôt « block » (computed value).
Je pense également que le computed value est block, mais il a un design de inline-block (affichage aligné et taille du contenu)
Oui, exactement comme les floats 😉
Bon, je teste….
flex-flow et flex-direction sont inutiles, ils définissent les valeurs par défaut.
float, clear et vertical-align sont ignorés avec flex.
z-index et bottom ne sont pris en compte que si on utilise du positionnement absolu/relatif/fixé, c’est pas le cas ici
Le « display: block » ne me semble pas utile.
Le width ne semble pas utile que l’élément va grossir ou rétrécir en fonction des besoins, au pire on pourra simplifier « width » et « shrink » avec un « flex: 1 1 250px »
Ça donnerait un truc comme ça.
.flex-container {
display: flex;
align-items: space-between;
}
.flex-item {
flex: 1 1 250px;
height: 250px;
}
Attention, il ne faut pas modifier les déclarations existantes, juste supprimer celles qui ne s’appliquent pas.
Je crois bien que personne n’a exactement la bonne solution, même si certains sont très proches. Je précise bien lesquelles ne s’appliquent pas. Si une propriété s’applique, il faut la conserver.
Notez qu’il y a un petit détail que personne n’a encore remarqué 😉
C’est bien le problème. Entre ce qui DOIT et ce qui DEVRAIT rester, il y a un monde. C’est par exemple pour ça que j’ai mis une différence entre z-index et bottom. Mais je suis impatient de voir ta solution, j’ai trouvé des cas vraiment sioux. 🙂
Justement, il y a une différence entre z-index et bottom dans notre cas 😉
C’est ce que je dis. Mais je suis parti du postulat: « lesquelles ne servent à rien ». Si on part du postulat : « lesquelles ne s’appliquent pas », alors il faut en supprimer moins que prévu.
Disons alors « quelles propriétés peuvent êtres supprimées sans qu’il n’y ait aucune incidence sur l’affichage et le comportement des éléments » (un stacking contexte étant une modification du comportement)
Bon au final avec ce retour, je dirais :
.flex-container {
display: flex;
}
.flex-item {
flex: 1;
z-index: -1;
bottom: 1em;
height: 250px;
}
Je crois qu’un z-index: -1; aurait peut-être été mieux compris
avec height, il peut y avoir de l’overflow donc z-index doit jouer
les réponses ci-dessus : si on accepte pas d’enfants de .flex-container sans classe .flex-item ou de doublon .flex-container.flex-item etc. là… surchauffe !
j’aurais des doutes avec des img.flex-item et le width (chrome et Fx agiraient de manières différentes ?)
Attention,j’ai changé bottom:0 par bottom:1em si ça peut d’influencer
Bonjour à tous,
.flex-container {
display: flex;
flex-flow: column nowrap; // comportement par défaut
align-items: space-between;
flex-direction: row; // comportement par défaut
}
.flex-item {
flex: 1; // pour moi comportement par défaut
display: block; // inutile positionnement parent flex
align-content: center;
flex-shrink: 1; // inutile
float: left; // inutile positionnement parent flex
clear: both; // mais pourquoi donc ?
z-index: 1; // inutile vous avez vu du chevauchement quellques part
bottom: 1em; // inutile ???
vertical-align: top; // comportement par défaut
width: 250px; // flexible en largeur
height: 250px; // inutile car flexible selon le contenu
}
Alors je pense que l’on peut faire le ménage pour que cela donne au final :
.flex-container {
display: flex;
align-items: space-between;
}
.flex-item {
align-content: center;
}
J’espère avoir bien intégrer ton livre Raphaël (même si je galère encore avec la notion des flex-shrink et flex-grow) et avoir bien fais mes devoirs.
flex: 1; // pour moi comportement par défaut
–> houla, non malheureux, ce n’est pas le comportement par défaut !Reste plus grand chose en définitive 🙂
Hello.
Au final:
– je n’avais pas percuté sur le
space-between
avecalign-items
. Vicieux !– le
z-index
pour moi devait être enlevé car différence entre celles qui s’appliquent et celles qui ne servent à rien. Mais je savais pour le stacking context.–
vertical-align
, là j’en savais rien, mais sur un malentendu…Par contre, il reste 2 cas :
display
etwidth
:–
display
, je me suis dit que certains éléments devaient ne pas utiliserblock
par défaut, et que donc il était utile de le garder. Et effectivement, par exemple avec untable.flex-item
, sansdisplay:block
, il ne prends pas la taille restante. Bug ou feature ?–
width
, j’ai dit que c’était inutile, tout en gardant en tête quewidth
peut être la valeur préférée (par défaut) dans certains cas, et qu’elle était aussi en jeu pour les éléments remplacés et qui ont un ratio à respecter. Après quelques tests, il y a des différences entre Chrome et Firefox. Dans Chrome,width
peut avoir un impact sur la taille des<imgs>
,<iframe>
, surement d’autres éléments aussi (<input>
,<fieldset>
, etc.). Tu as des infos ?Le bin pour tester ça: http://jsbin.com/baxixu/edit?css,output
Hello et merci pour cette analyse détaillée.
<table>
est qu’il possède des<tbody>
,<tr>
, etc. qui ont tous les valeurs dedisplay
exotiques. Du coup, même si le<table>
est bien un flex-item, sa descendance casse un peu le contexte. Ceci dit, tu as raison : toutes les valeurs semblent fonctionner sur cet élément… saufdisplay: table
min-width: auto
sur les éléments « inline remplacés » : https://blog.goetter.fr/2015/10/30/flexbox-a-casse-mes-images-responsive/ Il suffit de rajoutermin-width: 0
sur le flex-item en effet, mais c’est un peu tiré par les cheveux 😉Point 1 : Oui
display: table
« casse » le flex. Je l’ai supposé en me fiant à ce tableau, mais dans le contexte Flexbox, je n’en savais rien. Après lecture de la spec, il semble que la même règle s’applique.Point 2, OK, donc c’est bien un bug.
En tout cas merci, tu m’auras bien fait chercher les cas tricky. 😉
Le cas
table
est intéressant. Comme mentionné dans ma réponse à Jonathan, je m’attendrais à ce que la « computed value » soitblock
, pastable
. Dans l’example avec l’image, la « computed value » pour cette dernière estblock
; et cela même si on lui appliquedisplay:inline-block
.Dans mon esprit,
display
est donc supposé prendre une valeur définie (block
) quelque soit le style de l’élément (comme le faitfloat
avecnone
). Voir « blockification »: https://www.w3.org/TR/css-display-3/#blockificationMais ça n’a pas l’air d’être le cas ici avec
table
.Si je m’intéressais plus que ça a flexbox je ferais des recherches mais là je compte plutôt sur Raphaël pour des éclaircissements. Alors bug ou pas bug?
Bon sang mais c’est bien sûr. Le fameux tableau (en plus pas d’excuse, j’ai le même sur mon site et slides).
Merci Vincent!