Bonjour à tous,
J'utilise Bootstrap depuis toujours et me suis retrouver face à certaine limite de la grille comme trop de class à écrire se qui rend mon HTML illisible.
Pour réglé mon problème je me suis dit pourquoi pas un autre framework css mais là encore et toujours un gros manque sur la personalisation des classes et souvent trop de chose par rapport à mon utilité.
J'ai donc fais du sur mesure et dans la foulé utilisé les flexbox qui me facinaient tant, je vous demande donc votre avis quand à la viabilité de ma grille et partage par la même mon LESS qui donnera peut être des idées à certain.
// //
///// Gestion des medias queries
// //
/**
* Fournis tous les outils permetant la création et la gestion d'une grille flexible
* Par défaut une grille de 12 est crée et peu être utilisé simplement en ajoutant la
* class 'grid12' au wrapper, les cellules peuvent être de taille différente en fonction
* de la taille du viewport. Les tailles se précise avec une class de type 'ds2' où 'd' est
* le préfixe du device, 's' span et 2 la taille. Les offset sont aussi pris en charge de la
* mêmes manière que les span soit 'do2' device, offset, cellule sauté. Des class facilitant
* l'alignement ont aussi été définis et s'utilise de la façon la plus simple, 'jc-fs' ou 'ai-ss'
* pour réciproquement justify-content: flex-start ou align-items: space-stretch. La posibilité
* d'aligner individuelement une cellule ou de les réordonnés se font simplement pas l'ajout de
* 'as-c' pour align-self: center et 'order2' pour order: 2. Les class peuvent êtres chaîné
* afin de simplifier la lecture du code par example grid12_jc-c_ai-ss pour une grille stretch centré
* ou Ds2_Ts4 pour un desktop span 2, tablette span 4. Inconvéniant: la lecture des class par le css
* peu poser des problèmes si ces termes sont utilisés pour d'autre chose d'où la possibilité de
* changer n'importe quel terme dans les variables.
**/
/**
* ToDo: Ajouter les devices+ et device- dans les @media query pour facilité l'utilisation
**/
////
// Variables
////
@columns: 12; // Nombre de colonne par défaut
@gutter: 1em; // Taille de la goutière par défaut
@grid-prefix: 'grid'; // Préfixe des classes wrapper
@span-prefix: 's'; // Préfixe des classes wrapper
@offset-prefix: 'o'; // Préfixe des classes wrapper
// @desktop-xl: @desktop-xl; // ~"only screen and (min-width: ...)"
// @desktop-l: @desktop-l; // ~"only screen and (min-width: ...) and (max-width: ...)"
// @desktop: @desktop; // ~"only screen and (min-width: ...) and (max-width: ...)"
// @tablet: @tablet; // ~"only screen and (min-width: ...) and (max-width: ...)"
// @mobile: @mobile; // ~"only screen and (max-width: ...)"
@desktop-xl-prefix: 'dxl'; // Préfixe des classes responsive desktop-xl
@desktop-l-prefix: 'dl'; // Préfixe des classes responsive desktop-l
@desktop-prefix: 'd'; // Préfixe des classes responsive desktop
@tablet-prefix: 't'; // Préfixe des classes responsive tablet
@mobile-prefix: 'm'; // Préfixe des classes responsive mobile
@justify-content-prefix: 'jc-'; // Préfixe des classes d'alignement horizontal
@justify-content-start: 'fs'; // Suffixe flex-start
@justify-content-end: 'fe'; // Suffixe flex-end
@justify-content-center: 'c'; // Suffixe center
@justify-content-between: 'sb'; // Suffixe space-between
@justify-content-around: 'sa'; // Suffixe space-arround
@align-items-prefix: 'ai-'; // Préfixe des classes d'alignement vertical
@align-items-start: 'fs'; // Suffixe flex-start
@align-items-end: 'fe'; // Suffixe flex-end
@align-items-center: 'c'; // Suffixe center
@align-items-stretch: 'ss'; // Suffixe stretch
@align-self-prefix: 'as-'; // Préfixe des classes d'alignement vertical
@align-self-start: 'fs'; // Suffixe flex-start
@align-self-end: 'fe'; // Suffixe flex-end
@align-self-center: 'c'; // Suffixe center
@align-self-stretch: 'ss'; // Suffixe stretch
@order-prefix: 'order'; // Préfixe des classes de réordonnement (et oui ça se dit)
////
// Mixin span
////
.grid-span(@columns: @columns, @gutter: @gutter, @span: 1) {
width: ~'calc(100% * @{span} / @{columns} - @{gutter} - .01px)';
}
////
// Mixin offset
////
.grid-offset(@columns: @columns, @gutter: @gutter, @offset: 1) {
margin-left: ~'calc(100% / @{columns} * @{offset} + @{gutter})';
}
////
// Mixin grid
////
.grid(@columns:@columns, @gutter:@gutter) {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-left: -@gutter;
& > * {
flex: 0 0 auto;
.grid-span(@columns, @gutter, 1);
margin-left: @gutter;
margin-bottom: @gutter;
background: #000;
}
}
////
// Mixin loop-span
////
.loop-span(@index, @device: '') when (@index > 1) {
& > [class*="@{device}@{span-prefix}@{index}"] {
.grid-span(@columns, @gutter, @index);
}
.loop-span(@index - 1, @device);
}
////
// Mixin loop-offset
////
.loop-offset(@index: @columns - 1, @device: '') when (@index > 0) {
& > [class*="@{device}@{offset-prefix}@{index}"] {
.grid-offset(@columns, @gutter, @index);
}
.loop-offset(@index - 1, @device);
}
////
// Mixin loop-order
////
.loop-order(@index: @columns, @device: '') when (@index > 0) {
& > [class*="@{device}@{order-prefix}@{index}"] {
order: @index;
}
.loop-order(@index - 1, @device);
}
////
// Mixin grid-responsive
////
.grid-responsive(@grid-prefix: @grid-prefix, @columns: @columns, @gutter: @gutter) {
[class*="@{grid-prefix}@{columns}"] {
.grid(@columns, @gutter);
@media @desktop-xl {
.loop-span(@columns, @desktop-xl-prefix);
.loop-offset(@columns - 1, @desktop-xl-prefix);
}
@media @desktop-l {
.loop-span(@columns, @desktop-l-prefix);
.loop-offset(@columns - 1, @desktop-l-prefix);
}
@media @desktop {
.loop-span(@columns, @desktop-prefix);
.loop-offset(@columns - 1, @desktop-prefix);
}
@media @tablet {
.loop-span(@columns, @tablet-prefix);
.loop-offset(@columns - 1, @tablet-prefix);
}
@media @mobile {
.loop-span(@columns, @mobile-prefix);
.loop-offset(@columns - 1, @desktop-prefix);
}
}
}
////
// Attribut justify-content
////
[class*="@{grid-prefix}"] {
&[class*="@{justify-content-prefix}@{justify-content-start}"] {
justify-content: flex-start;
}
&[class*="@{justify-content-prefix}@{justify-content-end}"] {
justify-content: flex-end;
}
&[class*="@{justify-content-prefix}@{justify-content-center}"] {
justify-content: center;
}
&[class*="@{justify-content-prefix}@{justify-content-between}"] {
justify-content: space-between ;
}
&[class*="@{justify-content-prefix}@{justify-content-around}"] {
justify-content: space-around ;
}
}
////
// Attribut align-items
////
[class*="@{grid-prefix}"] {
&[class*="@{align-items-prefix}@{align-items-start}"] {
align-items: flex-start;
}
&[class*="@{align-items-prefix}@{align-items-end}"] {
align-items: flex-end;
}
&[class*="@{align-items-prefix}@{align-items-center}"] {
align-items: center;
}
&[class*="@{align-items-prefix}@{align-items-stretch}"] {
align-items: space-stretch ;
}
}
////
// Attribut align-self
////
[class*="@{grid-prefix}"] {
& > [class*="@{align-self-prefix}@{align-self-start}"] {
align-self: flex-start;
}
& > [class*="@{align-self-prefix}@{align-self-end}"] {
align-self: flex-end;
}
& > [class*="@{align-self-prefix}@{align-self-center}"] {
align-self: center;
}
& > [class*="@{align-self-prefix}@{align-self-stretch}"] {
align-self: space-stretch ;
}
}
////
// Attribut order
////
[class*="@{grid-prefix}"] {
@media @desktop-xl {
.loop-order(@columns, @desktop-xl-prefix);
}
@media @desktop-l {
.loop-order(@columns, @desktop-l-prefix);
}
@media @desktop {
.loop-order(@columns, @desktop-prefix);
}
@media @tablet {
.loop-order(@columns, @tablet-prefix);
}
@media @mobile {
.loop-order(@columns, @mobile-prefix);
}
}
////
// Grille par défaut
////
.grid-responsive();
Au passage la grille ne fait pas plus de 12k minimifier, si vous avez des questions ou des suggestions je suis pas loin :p
PS: Pas encore pensé à la compatibilité pour du local ça ne me presse pas
Salut,
Aurait-tu un exemple d'utilisation ? Par exemple un codepen ? Car cette fonction LESS m'intéresse :)
Hello @betaWeb,
Tu peux tester facilement le code en compilant le less à défaut je te laisse un petit lien sur code open http://codepen.io/Niramar/pen/jPQzLK?editors=110 histoire de pourvoir tester et je posterais le résultat une fois en ligne sur mon propre site mais comme on migre à la dernière minute de CakePhp à Laravel on doit refaire tout le backend et c'est pas avant 2 bons mois je pense si tu as des question on besoin de plus de commentaire sur le less hésite pas et demande je reste à ta dispo.
PS: Les offset on mal été pensé je revidrais dessus quand j'aurais le temps désolé il faudra juste changer les selecteur dans les loops histoire de pouvoir les utilisés conjointement avec les span