alsacreations / KNACSS

feuille de styles CSS sur-vitaminée
http://www.knacss.com
Do What The F*ck You Want To Public License
555 stars 116 forks source link

KNACSS v6 : conventions de nommage des classes #209

Closed raphaelgoetter closed 8 years ago

raphaelgoetter commented 8 years ago

Réflexions autour des choix de nommage et de "namespacing" dans un framework tel que KNACSS pour éviter les collisions avec d'autres frameworks, outils ou CMS...

Pourquoi ? Pour être cohérent sur chaque projet, et ne pas "casser" si plusieurs frameworks sont utilisés en même temps.

EDIT : infos fraîches...

La convention générale de nommage de KNACSS devrait être :

Utilisé notamment par ITCSS et SMACSS. cf. https://github.com/jonathanlevaillant/atomic-builder

Débuter les classes par une lettre majuscule : .Media, .Grid, .Inbl, .W30, .Nav, .Container, .Clearfix etc.

Utilisé (uniquement ?) par Atomic CSS de Yahoo!. cf. http://acss.io/frequently-asked-questions.html#why-are-atomic-classes-capitalized-as-far-as-i-know-no-other-framework-does-that-

Namespacing option 3 : préfixe dédié

Débuter les classes par un préfixe dédié à KNACSS : .kn-media, .kn-grid, .kn-inbl, .kn-w30, .kn-nav, .kn-container, .kn-clearfix etc.

Utilisé notamment par Pure CSS de Yahoo! (ex. .pure-g, .pure-u-md-1-3, .pure-button) cf. http://purecss.io/grids/

Namespacing option 4 : pas de namespacing

On ne fait rien de particulier et on prie pour qu'il n'y ait pas de collision avec d'autres frameworks ou CMS : .media, .grid, .inbl, .w30, .nav, .container, etc.

Utilisé par pas mal de frameworks, genre :

blupdew commented 8 years ago

Nommage général : validé

L'inconfort apporté par plus de namespacing me semble supérieur à l'inconfort de devoir résoudre un conflit potentiel de classe avec une autre feuille de styles (qui se voit rapidement).

jnoesser commented 8 years ago

OK pour le nommage général.

Namespacing option 1 préfixes "fonctionnels" : pas super fan, c'est complexe, faut bien réfléchir en amont (notamment en phase design) et pas forcément toujours adapté à nos intégrations (on y retrouve bien plus souvent des composants plutôt que des objets réutilisables par exemple).

Namespacing option 2 majuscules : bof, pour moi CSS = pas de majuscule ^_^ (plutôt dédié au dev back)

Namespacing option 3 préfixe dédié : c'est plutôt pas mal pour s'y retrouver dans l'inté, on voit de suite quelle class provient de Knacss, pas de conflit avec les CSS plus spécifiques ou celles des autres frameworks.

Namespacing option 4 pas de namespacing : c'est ce qu'on utilise déjà, ça me convient bien pour l'instant.

raphaelgoetter commented 8 years ago

Merci pour ces premiers retours.

Pour ajouter un peu de piment, je rajoute une hypothèse pour étayer l'intérêt du namespacing : le projet qui combine KNACSS + Bootstrap + des styles persos (oui, ils existent ces projets, notamment chez certains clients)

Du coup, quand la classe .row vaut width:100%; clear:both dans un framework, display: table dans l'autre et peut-être autre chose dans tes styles persos et qu'en Responsive chacun a ses propres variations aussi, tu gères comment ?

Ou comment éviter les collisions avec certains CMS (SPIP si tu m'écoutes) qui ajoutent automatiquement des .fr sur <html> (= "français") alors que ton framework dit que .fr = "float: right", etc. ?

PS : que personne ne me réponde que SPIP n'est plus utilisé ;)

jnoesser commented 8 years ago

J'avoue que j'utilise très peu les class utilitaires de type .row, .w30… à part .grid. Nos inté sont trop complexes, pour une meilleure maintenabilité du code je préfère tout gérer dans la CSS (via BEM). Il y a bien entendu des class réutilisables (pour les boutons, les éléments de formulaires et autres objets réutilisables) mais non liées à Knacss.

Les class utilitaire de Knacss sont pratique pour des petits projets, une page de blog toute simple qu'on veut monter rapidement, sans design trop poussé, sans trop de modifications à l'avenir, sans grosse équipe de dev derrière, ni de gros CMS. On ne devrait pas trop rencontrer de multiples frameworks sur ce genre de projet. ^_^

raphaelgoetter commented 8 years ago

@jnoesser c'est bien vu, tu distingues deux types de projets et donc deux usages différents de KNACSS (corrige-moi si je me trompe) :

  1. le "gros" projet, où tu n'utilises que très peu les classes utilitaires / atomiques, et beaucoup de classes d'objets non dépendants d'un framework. (en clair, pour toi il n'y aurait même pas vraiment besoin d'un framework pour ce type de projet)
  2. le petit projet où au contraire les classes utilitaires rapides sont utiles pour toi.

Tu as sans doute raison de distinguer les deux. Par contre, vu que les frameworks de l'envergure de Bootstrap ont été avant tout conçus pour être utiles sur de très gros projets, je m'interroge quand même sur notre façon de procéder (sommes-nous tout simplement "trop forts en CSS par rapport à la moyenne" ? ;)

Les gens que je côtoie en formation, qui utilisent en masse Bootstrap, et parfois KNACSS, n'utilisent malheureusement que les classes utilitaires, sur des gros projets ou non. Simplement parce qu'ils ne savent pas (et ne souhaitent pas savoir) comment ça fonctionne derrière dans le CSS et qu'en rajoutant une classe HTML "ça marche".

Sinon, le problème évoqué précédemment reste le même : qu'on s'en serve ou pas dans KNACSS, la classe .fr signifie float: right, elle est en dur dans le CSS donc s'applique qu'on le veuille ou non dès lors qu'elle apparaît dans le HTML. Or, SPIP l'ajoute systématiquement dans la balise <html>. Il y a donc bel et bien un problème de conflit de nommage à régler, et surtout à empêcher quelque soit l'outil appliqué par dessus KNACSS (et que l'on ne connaît bien évidemment pas).

hiwelo commented 8 years ago

@raphaelgoetter dans les cas genre SPIP, le souci peut être facilement réglé par l'utilisation d'un namespace, non ?

raphaelgoetter commented 8 years ago

@hiwelo c'est justement l'objet de toute cette discussion justement, de choisir le futur namespace de KNACSS ;)

hiwelo commented 8 years ago

Non mais ce que je voulais dire, c'était le laisser sans namespace, et utiliser Scss pour indiquer si nécessaire un namespace personnalisé.

raphaelgoetter commented 8 years ago

justement, le choix actuel de namespace dans le SCSS est "namespacing option 3", avec le préfixe dédié, et j'avoue - comme tous les intervenants précédents (huhu) - être très mitigé par ce choix, d'où la discussion.

https://github.com/alsacreations/KNACSS/blob/master/sass/_config-variables.scss#L70

Mais je note que tu penches pour l'option 3.

EDIT : sans oublier qu'une bonne partie des utilisateurs optent pour la version non-SCSS et se retrouvent avec le problème initial

hiwelo commented 8 years ago

Après, par rapport au nommage général la seule remarque que j'ai à faire c'est que si doucement on peut remplacer les is- et has- par des aria-attributes similaire on y gagnerait je pense. Mais c'est côté CSS & côté JS (ping @blupdew )

Genre .is-hidden, j'ai parfois l'impression que c'est un petit superflu aujourd'hui :)

jnoesser commented 8 years ago

@raphaelgoetter on est peut être un peu trop fort·e en CSS ouais ;) Et qu'avec des multiples class, Boostrap ou pas, on fini toujours par s'arracher les cheveux à un moment dans le projet (surtout quand cela implique du RWD ).

Je pense que tout dépend du contexte du projet, ceux qui utilisent Bootstrap ou Foundation sur de très gros projets doivent sans doute concevoir leur maquette et ergonomie en fonction du framework, ce qui n'est pas notre cas par exemple.

Pour le problème avec .fr, il faut effectivement revoir le nommage pour ne pas être en conflit avec certains CMS ou module CSS/JS (j'ai déjà vu par exemple des modules de langswitcher, où chaque langue a sa class, dont .fr pour la France par exemple) (du coup l'option 3 répond bien à la demande ^_^).

raphaelgoetter commented 8 years ago

si doucement on peut remplacer les is- et has- par des aria-attributes similaire on y gagnerait je pense.

oui sans aucun doute lorsqu'ils existent, mais on sort du cadre d'un framework

il faut effectivement revoir le nommage pour ne pas être en conflit avec certains CMS ou module CSS/JS

voilà tout l'objet de la discussion : à partir du moment où on ne peut pas prévoir quels sont les conflits potentiels actuels et à venir, quelle serait la meilleure méthode aujourd'hui pour les éviter avant qu'ils n'arrivent plutôt que de devoir les résoudre.

jnoesser commented 8 years ago

@hiwelo yep bien vu, depuis quelques temps on essaie avec @blupdew (sur le dernier projet par exemple) d'utiliser aria-hidden="true" ou aria-hidden="false" plutôt que is-hidden ou is-visible.

hiwelo commented 8 years ago

@raphaelgoetter oui et non, c'est aussi au framework d'essayer de pousser les bonnes pratiques. Dans le v6, il pourrait être bien de dire que bon .is-hidden et .is-disabled c'est du passé ;)

C'est les deux seules qui sont présentes dans Knacss, on peut tenter de les enlever non ? :)

Et oui @jnoesser sur le projet applicatif sur lequel je travaille là c'est pareil. Avec Laure, on a retiré toutes les classes du genre pour des attributs ARIA. Après côté aria-hidden vu qu'en CSS j'utilise un sélecteur [aria-hidden] je préfère l'idée d'ajouter / supprimer aria-hidden en JS plutôt que le true / false mais globalement on fait la même chose :D

raphaelgoetter commented 8 years ago

Ce ne sont malheureusement pas les seules, ce serait trop facile. Ceci dit, rien n'empêche d'ajouter les versions [aria-hidden] à la liste ;)

https://github.com/alsacreations/KNACSS/blob/master/sass/_override-helpers.scss#L5

hiwelo commented 8 years ago

Bah ce sont les seules à modifier. .visually-hidden n'a pas de variante ARIA, du fait même de sa raison d'être 😸 .is-unstyled c'est typiquement le genre de chose qui n'a pas de sens sémantique puisque… c'est du style.

Mais oui, déjà commencer par ajouter [aria-hidden] (ou [aria-hidden="true"] à voir avec @jnoesser ) ce serait pas mal 😸

GaetanBt commented 8 years ago

Hello, je vois parler de styles posés sur des attributs aria-hidden et je me demande un truc. Comment vous géreriez le cas ou un élément possède cet attribut parce qu'il est purement décoratif (prenons un séparateur d'éléments dans un fil d'Ariane) et que vous ne voulez pas qu'il puisse être retranscrit mais que vous voulez quand même qu'il soit visible ?

Sinon pour ma part, j'utilise l'attribut hidden pour ça.

hiwelo commented 8 years ago

Quand j'ajoute des éléments purement décoratifs en général, comme un séparateur d'éléments dans un fil d'ariane, il s'agit pour moi de pseudo-éléments CSS.

Dans une séparation sémantique / style, le purement décoratif devrait prendre place dans le CSS et ne pas "polluer" le HTML. (c'est d'ailleurs aussi pour cette raison que je n'utilise pas les classes utilitaires de Knacss en général, comme @jnoesser 😸 , qui restent une logique de style dans un document sémantique 😸 )

devlint commented 8 years ago

Question compliquée comme tu l'indiques et qui mène forcément au débat notamment face à tes utilisateurs :

Si je me concentre uniquement sur la grille, vu que c'est le sujet qui m'intéresse le plus, les collisions sont multiples, entre les noms des classes de Knacss vs. celui d'un autre vendor (qu'il s'agisse de Bootstrap ou d'un plugin JS livré avec une feuille de style ou autre chose) ; et les sélecteurs css utilisés (genre [class*="grid-"]) avec l'utilisation directe du .css (<div class="ingrid-qqch">) Si pour une raison quelconque tu veux utiliser gridlex + knacss en appelant les 2 fichiers css directement on rentre en collision : d'où la nécessité de peut-être avoir de base les namespaces kn- & gl- paramétrés en variable...

tneels commented 8 years ago

Salut. Les projets qui utilisent plusieurs framework ne font pas la majorité. Je trouve un peu dommage de "pénaliser" tous les autres en faisant des classes à rallonge.

Pour cette raison l'idée d'avoir un préfix en variable comme le propose @devlint me plait bien. Chacun y trouve son compte.

julianoL commented 8 years ago

Bonjour bonjour,

j'arrive un peu tard dans la discussion, je n'ai donc pas tout relu !

Pour ma part, j'utilise essentiellement WP. Que celà soit dans la création d'un projet, la reprise de site d'un client ou la création de plugin et franchement, les collisions sont nombreuses !

Ne serais-ce que reprendre le travail d'un FrontEnd ou Dev, les façons de travailler diffères, je pense indubitablement à l'OPTION 3.

Même pour les petits projets, on a, à un moment donné, un client qui va nous demander une fonctionnalité. On va prendre la solution la plus rapide et facile à mettre en place grâce à un autre framework, utilisant lui aussi un jquery ou autre, en découle des nouvelles css, js...

Plutôt d'accord avec devlint

Pour l'instant je n'ai pas encore utiliser KNACSS, mais je compte l'utiliser prochainement en créant un thème WP surtout aussi s'il y a une version SASS :)

nico3333fr commented 8 years ago

Attention à l'utilisation trop rapide des attributs ARIA, cela peut poser des problèmes, faites gaffe !

Notamment sur VoiceOver : si ce dernier détecte des attributs ARIA, il passe en mode application et demande l'utilisation de raccourcis supplémentaires, très très chiants pour l'utilisateur. Si on est sur une pure application, no soucy, sinon ça peut être pénible. Cf : https://twitter.com/goetsu/status/745184189750874112

J'ai dû modifier les paramètres par défaut de certains de mes plugins accessibles pour éviter des bugs : cf https://github.com/nico3333fr/jquery-accessible-hide-show-aria/commit/e0518c5c614b723013a5a9d6dab362620d7f9fd5

Comme vous pouvez le voir, ce n'est pas intuitif, sur 4 attributs ARIA, mon plugin en utilise un par défaut et pas les autres. En pratique, testez, testez, testez.

Je reviens tout à l'heure, votre discussion sur CSS est très intéressante, et vous allez rigoler quand vous allez voir ce que je vais ajouter ;)

PhilippeVay commented 8 years ago

Contexte personnel :

(*) pas vraiment SMACSS en fait, juste le nommage .module .module-qqch { } et is/has/js mais par ex. pas les préfixes .l- pour du layout (parce que je n'ai pas vraiment eu à faire du layout en fait :o).

Nommage général : OK pour les préfixes is, has et js mais pas d'accord pour les doubles tirets et undescore à la BEM. Je n'ai aucun souci avec le simple tiret et tant que ça convient je préfère de loin la simplicité de ce tiret (jusqu'à présent, je n'ai jamais eu de confusion entre ce qui serait une classe dans un composant et une classe-variante sur le parent du composant).


Namespacing option 1 : préfixes "fonctionnels"

C'est une solution à un problème que je n'ai pas (confusion sur le rôle que pourrait avoir une classe nommée d'une certaine manière), je passe si possible

Namespacing option 2 : majuscules

Je préférerais m'en passer : pour les détails du quotidien, c'est fatigant pour le poignet à taper (aller chercher la touche Maj/Shift alors que de temps à autre j'ai déjà le poignet douloureux à force de Ctrl-S Alt-Tab Ctrl-R ou F5 200 fois par heure) et c'est une source d'erreur (oublier la majuscule...) Sur le fond, à mon avis c'était une super idée pour le 1er qui l'a eu (ça remplace un préfixe) mais si plusieurs frameworks/CSS utilisent la majuscule pour se distinguer des autres, bah ils se collisionnent entre eux :p (et si je vois un .media et un .Media je ne vois pas comment m'y retrouver ! Entre un .autreframework-media et .Media ce serait par contre OK)

Namespacing option 3 : préfixe dédié Namespacing option 4 : pas de namespacing

(**) encore que rien ne t'empêche techniquement© de générer un knacss-sans-prefixe.css et un kn-knacss.css


Se passer d'.is-hidden au profit d'[aria-hidden]

Je n'ai pas de souci avec .is-hidden et j'en ai avec l'utilisation partout où c'est possible des attributs ARIA comme sélecteurs CSS. Mais si ça se résume à juste aria-hidden oui pourquoi pas. Par contre styler [aria-level] non : je style .module-title mais pas h3, [aria-level="3"] { } (ni h3 tout seul hein) Ça évite dans le JS d'avoir à gérer et la classe et l'attribut : même si ça ne me dérangeait pas jusqu'à présent, c'est une amélioration. Je pense surtout créer une fonction JS alsa_hide() qui fera ça de manière transparente et pour changer de méthode ça se passera à un seul endroit :) SPIP et .fr : à sa décharge SPIP date de bien avant l'utilisation de classes partout (et peut-être qu'il survivra à pas mal de méthodos, modes et cie :D). La collision est bien embêtante mais il n'y en a pas tant que ça (et elle se règle plus facilement que celle avec GMaps qui lui détectait nimp' en JS…)

nico3333fr commented 8 years ago

Huhu, c'est rigolo quand je lis vos commentaires, ça montre une variété assez intéressante de cas de figures.

Effectivement, même si Röcssti est moins connu/utilisé que Knacss, je constate certaines tendances aussi : les gens ne customisent pas et utilisent bêtement tout alors qu'ils n'ont p-e besoin que de 3 classes tout au plus (et ce, même si customiser n'est pas d'un niveau difficile, loin de là). Pour mon plus grand désespoir :-\

sur l'utilisation des classes utilitaires

Marrant que vous parliez d'intés trop compliquées, j'ai exactement le même ressenti. J'ai l'impression que désormais, pondre de la CSS soi-même sur des intés non triviales me place automatiquement au-dessus de la mêlée.

Par contre, sur les classes utilitaires, pas forcément d'accord : en effet, cela est très apprécié des débutants qui ne veulent pas se prendre la tête, mais cela sert aussi l'expert. Typiquement, sur la dernière inté assez difficile que j'ai faite, les classes utilitaires m'ont permis d'aller chercher de la facto à grande échelle, en tirant sur de l'atomic CSS (j'utilisais déjà les classes onmobile-, etc.).

Résultat : une CSS de moins de 20ko (minifiée, mais non gzippée) au lieu de beaucoup plus avec des techniques plus "classiques".

namespacing

Sur le nommage général, je dis +1, car j'utilise le même. C'est simple et assez clair.

Namespacing option 1 : vraiment pas fan (du point de vue du namespacing). J'ai eu l'impression de sur-ingéniérer à chaque fois que j'utilisais ça. Il n'y a guère que sur des intés vraiment ultra-compliquées ou je trouve que l'investissement se rentabilise. J'ai plus ou moins résolu ce "problème" en ordrant mieux mes CSS : sections pour les modules, section pour les composants, section pour le sculptage global du template, etc. Cela demande un peu de rigueur, mais bon, entre gens responsable, cela ne dérange pas :)

Namespacing option 2 : quelle horreur ! :-o Autant en pratique que l'idée, c'est cacapabomifreux.

Namespacing option 3 : ah, je trouve cette idée intéressante. Peut-être un poil bazooka, mais ça a le mérite d'être efficace et jusqu'au-bout-iste de l'idée de namespacing. Je vais y réfléchir pour Röcssti.

Namespacing option 4 : curieusement, gérer à la mimine, c'est parfois encore le plus simple. Autrement dit, ne pas le gérer. Après, ce qui pourrait suffire, c'est avoir un mini-moteur de recherche dans une CSS pour détecter les potentielles collisions avec la référence de Knacss (plus ou moins ce que j'avais fait sur un projet).

Collisions

Côté collisions, je n'ai que très peu eu le cas, j'ai eu plus de soucis avec de vieilles CSS qui n'avaient pas de conventions et dont chaque horreur écrite était une convention en soi, et venait foutre le bordaÿl avec une CSS qui arrive avec de vraies conventions posées. :)

Pour ARIA, comme je l'ai indiqué plus haut, attention. Je constate que je me sers en général surtout des sélecteurs d'attributs conjointement à des classes pour styler leurs états.

ryuran commented 8 years ago

https://suitcss.github.io/ l'option 2 ressemble beaucoup à ça.