BEM or not BEM




Bonjour à tous,

Après la lecture de l'excellent article de Tarh (http://www.alsacreations.com/article/lire/1641-bonnes-pratiques-en-css-bem-et-oocss.html) et l'ouvrage de Kaelig Deloumeau-Priget "CSS maintenables", je me suis lancé dans un nouveau projet d'intégration avec un syntaxe BEM.

Sur le papier cela me semble super mais dans les faits je trouve cela très verbeux et oblige à définir une classe pour le moindre élément html créant ainsi une feuille de style à rallonge.

Bref, je suis partagé : j'aime l'idée mais son application sur un petit projet ne me semble pas forcément très productive.

J'aimerais beaucoup avoir votre avis sur le question et surtout savoir si "dans la vrai vie" vous utilisez systématiquement une approche oocss ou BEM dans vos intégrations ?

D'avance merci.

Bien à vous.
Bonjour,

Je ne peux pas vraiment répondre au sondage : en effet, quand je code je suis a fond dans la logique OSCSS mais je déteste la syntaxe BEM.
Merci Olivier et quelle syntaxe utilises-tu ?

Pour ma part j'utilise le principe en de BEM en le simplifiant : block-element .modifier

Mais cela reste très verbeux :

<section class="sectionfond clear">
  <div class="w960p center">
    <div class="grid-2">
       <div class="promorevue">
          <img class="promorevue-visuel"src="img/revue.jpg" alt="revue" width="420" height="600">
          <h2 class="promorevue-titre">Nom de la revue</h2>
          <h3 class="promorevue-description">Description de la revue</h3>
          <a href="#" class="bouton primaire mts center">Commander ce numéro</a>
          <a href="#" class="promorevue-lien mts center">Découvrer les autres n° et revues</a>
        </div>
        <div class="promoliens">
          <a href="#" class="promoliens-eobs">
            <div class="promoliens-eobs-ico"><img src="img/ico-ebs-blanc.svg"></div>
	    <div class="promoliens-eobs-txt"><span class="promoliens-eobs-txtpetit">Mon lien</span><br><span class="promoliens-eobs-txtgrand">Promo/span></div>
	  </a>
          <a href="#" class="promoliens-sos mtm">
            <div class="promoliens-sos-ico"><img src="img/ico-sos-blanc.svg"></div>
	    <div class="promoliens-sos-txt"><strong>Mon lien</strong> Promo</span></div>
	  </a>
	</div>
      </div>
    </div>
</section>

Je débute dans les CSS et l'approche OOCSS donc je suis aussi humblement preneur de conseils avisés Smiley cligne

Bien à vous.
Modifié par dasys (29 Sep 2015 - 09:23)
BEM m'a toujours parue particulièrement overkill et ne cadre pas forcément bien avec un environnement déjà existant.

Je perfectionne ma propre méthode, basée sur un découpage entre structure de page, classes génériques (et modifiers), classes spécifiques. En limitant ces dernières au maximum.
Avec une syntaxe simple, c'est vraiment plus accepté, et applicable.

Ca répond à toutes les problématiques que je rencontre professionnellement, en terme de maintenabilité et performances.
Modifié par Nigel (30 Sep 2015 - 11:29)
Merci Nigel ! Cela me semble très intéressant comme approche.
Aurais-tu un exemple de structure issue de cette méthode maison ?
J'avais commencé à concevoir une lib embarquant quelques méthodes de travail, mais elle n'est pas complètement aboutie, ni à jour :

Exemple de page : http://www.nicolasbocquet.fr/ingredientsCSS/recipes.html
Feuille de styles : http://www.nicolasbocquet.fr/ingredientsCSS/stylesheets/ingredient.css
Projet github : https://github.com/nicolasbocquet/Ingredients-CSS

Le découpage de la feuille CSS peut te donner un exemple d'approche néanmoins. Tu peux partir de ça si tu veux, mais je te conseille plutôt d'en faire une à toi, correspondant aux cas que tu rencontres. Smiley cligne
Modifié par Nigel (30 Sep 2015 - 14:51)
Pour ma part, j'utilise les classes comme des espaces de nom, appuyés de quelques classes génériques comme '.active'. Je ne rencontre pas de problème de cascade dans mon code et celui-ci fait pourtant des centaines de lignes.

Si vous voulez des exemples suivez le lien dans ma signature pour voir mon code sur github...
Modifié par Olivier C (30 Sep 2015 - 19:30)
Bonjour à tous,

@Olivier C : impressionnant ton travail sur ton framework Scriptura ! J'utilise Knacss pour le moment mais j'apprécie la possibilité que tu offres de gérer la largeur des gouttières sans passer par un pre-processeur.

@Nigel : Merci pour les recettes CSS Smiley cligne

Merci encore,
Bien à vous.
BEM est un principe d'écriture de classes, ça ne t'oblige pas à écrire des classes uniques pour chaque élément. Il est évident que si tu as des éléments répétés plusieurs fois, il faut leur attribuer une classe plus générique ; mais ce nom de classe générique peut-être parfaitement raccord avec la syntaxe BEM.
Merci Manumanu !

J'ai fait une tentative de simplification au niveau du nommage des class html tout en conservant une approche "objet".

Je trouve que c'est un bon compromis au verbeux BEM.

Qu'en pensez-vous ?

Voila ce que ça donne :
http://codepen.io/dasys/pen/qOmbzX

HTML :
<ul class="menu">
  <li class="item">
    <a href="#" class="lien">
      <div class="image"><img src="http://dayoneapp.com/images/features/feature-icon-sync.png"></div>
      <label class="label">Lorem ipsum<br>dolor est</label>
    </a>
  </li>
  <li class="item">
    <a href="#" class="lien">
      <div class="image"><img src="http://dayoneapp.com/images/features/feature-icon-sync.png"></div>
      <label class="label">Lorem ipsum<br>dolor est</label>
    </a>
  </li>
</ul>


CSS :
.menu {
  display:table;
  height:70px;
  background-color:yellow;
  padding:0;
}

.menu>.item {
  display: table-cell; 
  vertical-align: middle; 
  width: 200px;
  background-color: red;
}

.menu>.item>.lien {
  display: table;
  margin: auto;
  background-color:aqua;
}

.menu>.item>.lien>.image, .menu>.item>.lien>.label {
  display:table-cell;
  vertical-align:middle;
}


D'avance merci,
Bien à vous.
.menu>.item>.lien>.image
.menu>.item>.lien
.menu>.item>.lien>.label

La spécificité de ces sélecteurs commence à devenir importante. Je pense que tu peux rendre les .image, .lien et .label plus génériques (et réutilisables dans un autre contexte, par conséquent).

.menu>.item me semble bien. Tu peux aussi aller jusqu'à remplacer les .item, par des .menuItem et les appeler directement
.menuItem{...}
Plus performant, peut-être moins utile, surtout si tu décides de définir des types de .menu différents, ce qui te ramenerait à revenir sur du .menuType1>.item {}

Généralement j'essaie de me limiter à un ou deux niveau(x) de spécificité.
A toi de voir ! Tout est question de limite à la spécifité que tu te fixes. Smiley cligne

La plus important n'étant pas quelle méthode officielle employer, mais de suivre les grands principes d'orthogonalité des CSS.
Modifié par Nigel (06 Oct 2015 - 09:47)
Merci infiniment Nigel pour ton éclairage : je vais essayer de me limiter deux niveaux de spécificité.

En tous cas j'aime bien cette syntaxe car elle contraint plus l'intégrateur de que le développeur qui pourra être plus libre de la nommage de ses class.

J'aurais juste à lui spécifier de définir un class pour chaque élément sans lui imposer BEM ou un autre OOCSS qu'il respectera... ou pas Smiley cligne

Bien à toi.
Comme le dit nigel, .item est probablement trop générique. Il y a des centaines d'éléments qui sont des "items", et qui par conséquent pourraient demander un css différent pour un même nom de classe. Le but est d'avoir des déclarations les plus légères possibles dans ton CSS : au mieux une classe, au "pire" deux et un sélecteur spécifique.

Donc ".menuItem" (ou autres variantes : .menu-item, .menu__item, etc.) est beaucoup plus approprié que ".menu > .item".

Mais l'un dans l'autre, être verbeux n'est pas un problème en soi, au contraire. C'est le même principe qu'avec les noms de variables ou de fonctions. Entre "uname_id($i)" et "getUserNameById($userID), y a pas photo sur la facilité de lecture. C'est un peu la même chose entre
.content {}
et
.main-page__content {}
et ce peu importe la syntaxe choisie. Smiley smile
Modifié par Manumanu (06 Oct 2015 - 15:49)
Attention ce n'est pas la même chose !

.content{} est une classe générique, et utilisable de manière globale dans différent contextes, alors que .main-page__content {} traine une spécificité à "main-page" de par son nommage.

Ceci étant la même chose entre .menuItem et .item.
Il peut être utile de laisser la possibilité que le style d'un .item soit utilisable dans un autre contexte qu'un .menu. Auquel cas .menu > .item sera plus approprié, puis plus tard pourquoi pas .list > .item :


.item {"A"}
.menu > .item {B + Hérite de "A"}
.list > .item {C + Hérite de "A"}


Avec .menuItem, nous perdons l'héritage:

.menuItem {B + "A"}
.listItem {C + "A" (doublon)}

Modifié par Nigel (06 Oct 2015 - 17:12)
Je n'ai pas voulu dire que c'était la même chose ; je me suis peut-être mal exprimé.

L'héritage a du bon oui, mais de façon maîtrisée. D'expérience, c'est rarement le cas dans un projet de plus de 3-4 pages. Le fait est que dans le premier cas, on va effectivement pouvoir bénéficier d'héritage ; mais on va très généralement devoir le contrebalancer avec des déclarations de plus en plus spécifiques, de ce genre :

.maClasse {
	color: blue;
	width: 60em;
	font-size: 1.25rem;
}

.contexte .maClasse {
	color: green; /* ici on veut avoir une autre couleur... facile ! */
}

.contexte .autreContexte .maClasse {
	color: blue; /* mais ici on veut retrouver la couleur d'origine... Obligé de re-surcharger */
	font-size: 1rem;
}

#grosProbleme .maClasse {
	/* et là c'est le drame, on tombe sur un ID... de fait, si on tombe sur un cas où .contexte .maClasse
 se trouve dans #grosProbleme, on est obligés d'écrire
 une surcharge encore plus lourdingue ci-après */
	color: red;
	width: 20em;
}

#grosProbleme .contexte .maClasse {
	/* la surcharge bien lourde, JUSTE pour retrouver du texte bleu... */
	color: blue;
}


Voilà le hic auquel je me confronte dès que je n'ai pas la possibilité d'imposer BEM dans un projet "multi-dev" où je ne suis pas le seul à travailler. En soi, on peut faire tout ce qu'on veut tant qu'on est maître du travail qui est fait. Dès qu'il échappe un tant soit peu à notre contrôle, un approche comme BEM (peu importe la syntaxe choisie) devient nécessaire pour la bonne maintenabilité du projet.

Enfin, c'est mon ressenti.
Modifié par Manumanu (06 Oct 2015 - 18:21)
Dans ce genre de cas, il est nécessaire de définir un cadre et des règles en effet !

.contexte .autreContexte .maClasse {


Pour ce cas je dirais que ceci peut souvent largement suffire :
.autreContexte .maClasse {


;)
Bien entendu ; je ne peux pas montrer de cas concret de problème de ce genre, ça prendrait des centaines de lignes pour que le problème devienne bien visible Smiley lol Néanmoins c'est représentatif.