Estilo, convenciones y metodologías generales de CSS. Parte II Sass, BEM, rscss, SMACSS, WTF?

Hola amigos dev! Vamos a continuar los temas tratados en la primera parte .
Hoy veremos más de cerca las diferentes metodologías de escritura CSS, como BEM, rscss, SMACSS. También se debe mencionar que las metodologías se pueden combinar (por ejemplo, OOCSS + BEM). Por supuesto solo si tiene sentido para nosotros. Eso es realmente algo importante. No es tan bueno usar chupar cosas solo porque son "geniales" ahora, muy a la moda, etc. No importa, en los próximos días, semanas o meses aparecerá algo "completamente nuevo e impresionante". 😉Pero este es un tema aparte, en el que no quiero perder el tiempo 😉, de forma correcta.
modernos-desarrolladores

Metodologías CSS: SMACSS

Vamos a empezar con SMACSS. Y debo decir que nunca usé este enfoque de organización y escritura de CSS en proyectos de la vida real. No se trata de que SMACSS apeste o algo así. Simplemente esta metodología no es cómoda para mí. Seguro que tiene muchas ventajas, solo para mi algunos detalles son molestos. PERO, por supuesto, puede ser muy bueno y cómodo para los demás. ¡Tu decides! Asi que…
SMACSS (Arquitectura escalable y modular para CSS), creada por Jonathan Snook, es una guía de estilo para el código CSS. En este enfoque, organizamos el código CSS por categorías (Base, Diseño, Módulo, Estado, Tema). Vamos a verlos más de cerca.
Base
Estilos básicos, generales. Este grupo de estilos es responsable de los valores predeterminados; aspecto predeterminado de los elementos de la página (márgenes, entrada, fuentes, ejemplo: normalize.scss).
Diseño
Los estilos de diseño definen la apariencia y la ubicación de elementos web y de página típicos, como encabezado, pie de página, barras laterales. En SMACSS (y no solo) se supone que se usa el prefijo "l-" para ellos.
Módulo
Los módulos en SMACSS son bloques de código independientes y reutilizables (IU), como el menú, el cuadro de búsqueda, los elementos de lista, etc. Podemos decir que son algo así como bloques en BEM . Los módulos generalmente se ubican en contenedores, dentro de los elementos de diseño.
El supuesto es que cada módulo debe ser independiente de los otros módulos. Debería funcionar de la misma manera en cada contenedor en el que lo colocamos. Por lo tanto, no cree estilos que dependan del contenedor principal.
Como ejemplo podemos considerar el módulo de menú:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
.menu {
  background: #00a;
}
.menu h1 {
  font-size: 20px;
}
.menu .menu-item {
  border: 1px solid #000;
}
...
Estado
Simplemente definen la apariencia del estado del elemento, dependiendo de la situación (por ejemplo, oculto, expandido, etc.). Contraemos o expandimos el menú, hacemos los elementos visibles u ocultos, movemos el cursor sobre un elemento y otras situaciones similares.
Ejemplo :
1
2
3
<div class="menu is-expanded">
  ...
</div>
Se recomienda definir dichos estados lógicos con el prefijo "is-", por ejemplo, "is-active".
Tema
Los temas generalmente se encuentran en proyectos más grandes, donde existen variantes (por ejemplo: diaria, nocturna, sexy, soleada, etc.), que definen el aspecto (y sensación) diferente para los elementos de Módulo y Diseño del proyecto.
SMACSS - ejemplo 1 :
1
2
3
4
5
6
7
8
9
// Layouts
.l-default {}
// Modules
.m-accordion {}
// States, mostly with prefix like &quot;is-&quot;
.is-active {}
.is-hidden {}
SMACSS - ejemplo 2 - mediaqueries: pu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dieciséis
17
.m-navigation {
  &amp;:after {
    @media screen and (min-width: 767px) {
      content: '';
      display: inline-block;
      width: 100%;
    }
  }
  li {
    display: block;
    @media screen and (min-width: 767px) {
      float: left;
    }
  }
}
Ver también
Este autor creó su propio estilo de guía basado en SMACSS y OOCSS:
Y el autor de SMACSS ejecuta el sitio web ( https://smacss.com ), donde podemos comprar o leer en línea un libro sobre esta metodología de CSS:

Vamos a conocer otras metodologías. 😎Tampoco es una sorpresa que encontremos las similitudes entre ellas.

Metodologías CSS: rscss

RSCSS presenta un enfoque diferente, principalmente bastante simple (es más pequeño en comparación con los otros). Podemos empezar a usarlo rápidamente; Puede ser bueno comenzar, si aún no está utilizando ninguna metodología.
RSCSS - Reasonable System for CSS Stylesheet Structure es una guía de estilo CSS con un simple conjunto de suposiciones. En rscss cada "bloque de construcción" es un componente. Además de los componentes, también distinguimos entre elementos, variantes y ayudantes.
Componente : una sola “pieza” de código UI, fácilmente reutilizable en muchos lugares de la aplicación; contiene elementos.
Elemento - Etiquetas HTML dentro de los componentes.
Variantes : variaciones de la apariencia predeterminada (apariencia) de un elemento.
Ayudantes - utilidades, herramientas de uso general.
Cuando estaba desarrollando un front-end pequeño usando Bootstrap , rscss y plantillas Slim ( http://slim-lang.com ), no me gustaba el prefijo "_" recomendado para los ayudantes. Código como este era raro
... 
.clearfix 
._divided10 
...
Actualmente, y sin importar qué metodología utilice, mis ayudantes siempre tienen el prefijo "h-", por ejemplo:
.h-split10
Rscss - un ejemplo simple :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dieciséis
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// ----------------------------------------------------------------
// Search form component.
// ----------------------------------------------------------------
.search-box {
  > .label {
    font-weight: 500;
    color: $color-base-blue;
  }
  > .field {
    // ...
  }
  // > input ...
  > .button {
    // ...
  }
  // Variants.
  &.-basic {
    color: $color-base-red;
  }
  &.-extended {
    color: $color-base-blue;
  }
  &.-hidden {
    display: none;
  }
}
Ver también :

Metodologías CSS: BEM

Finalmente, es hora de BEM! Es mi enfoque favorito, que utilizo en mis proyectos.
BEM ( Block Element Modifier ) es una metodología elaborada por los desarrolladores de Yandex. Este es un enfoque bastante simple para crear un código CSS modular y reutilizable.
BEM nos libera de la cascada. Aplicamos solo los estilos que realmente necesitamos. Además, los bloques principales no dependen de otros elementos. De esa manera, es mucho más fácil no solo mantener y modificar el código, sino también moverse (bloquear) a otros lugares, e incluso a otro proyecto.
En los supuestos BEM es ser :
- simple - la base se basa en el uso de la convención de nomenclatura BEM
- Modulares - Bloqueadores independientes y selectores de CSS.
- Elástico - tenemos mucho espacio para hacer que BEM sea cómodo - tal como nos gusta
Nota : es bueno saber que BEM se creó para proyectos, que deben publicarse rápidamente, PERO se mantienen desde una perspectiva a largo plazo. Y funciona muy bien en esa materia.
En BEM vemos nuestro código como :
- Bloques: por ejemplo, un botón simple, estilizado, menú o forma extendida, pensamos que el bloque es un componente reutilizable en nuestro proyecto (ejemplos: encabezado, contenedor, menú, casilla de verificación, entrada)
- elementos: elementos individuales, por ejemplo, un botón consiste en un enlace, con un texto y una imagen, el formulario tiene elementos de entrada, etc. (ejemplos: elemento de menú, elemento de lista, título de casilla de verificación, título del encabezado)
- modificadores: son solo clases adicionales, que modifican la apariencia de un bloque o elemento dependiendo del estado, por ejemplo, un elemento de menú activo después de pasar el cursor sobre el cursor (ejemplos: deshabilitado, resaltado, marcado, fijo, tamaño grande, color amarillo)
La metodología BEM da una estructura simple y comprensible. Creamos estilos basados ​​en las convenciones de los nombres.
BEM - convención de nomenclatura
BEM tiene la siguiente convención de denominación para las clases de CSS:
.block: la primera palabra en el nombre significa que la clase se aplica al bloque dado
__elemento: dos subrayados significan que la clase dada se refiere al elemento
–Modificador - dos guiones definen el modificador
Ejemplo :
1
2
3
4
5
6
7
8
9
10
11
// Block
.block {}
// An element associated with the block
.block__element {}
// Modifier of the block
.block--modifier {}
// Modifier of the element
.block__element--modifier {}
Se trata de la convención de nomenclatura básica. Nuestra tarea es simplemente pensar en cómo organizar los estilos para reflejar los requisitos de nuestro proyecto, de manera elegante y cómoda.
También podemos decir que BEM nos anima a pensar dos veces antes de complicar las cosas innecesariamente. Ejemplos a continuación.
El bloque representa y se opone, por ejemplo : 
- una persona 
- un menú 
- un formulario de inicio de sesión 
- un cuadro de búsqueda
etc.
El elemento es una parte del bloque, que cumple una función definida en su contexto, por ejemplo : 
- un encabezado (de la persona) 
- elemento del menú 
- una etiqueta, botón o campo de entrada
etc.
El modificador determina cómo representar las variaciones de un bloque o elemento, por ejemplo : 
- persona alta / baja 
- activo - elemento del menú resaltado 
- entrada expandida / contraída del formulario de búsqueda, bloque contraído
etc.
Ejemplos :
1
2
3
4
5
6
7
8
9
10
11
// Menu
.menu {}
.menu__item {}
.menu__item--is-active {}
// Person
.person {}
.person__head {}
.person__hand {}
.person--female {}
.person__hand--left {}
De esta manera, sabemos que la cabeza o la mano se refieren al contexto de la persona. Después de la decapitación, podríamos tener clases separadas, por ejemplo:
1
2
.head {}
.left-hand {}
Solo recuerda, que la cabeza puede pertenecer a una persona , pero también al perro, gato, mono, etc. Y en cada caso se verá diferente.🙂
Las características de Sass permiten escribir significativamente un código compatible con BEM.
Ejemplo - mixin :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@mixin button {
  padding: 0.6em 0.7em;
  // style ...
}
.button {
  @include button;
  background-color: $color-red;
}
.button--secondary {
  @include button;
  background-color: $color-green;
}
BEM - buenas prácticas
A toda prisa, podemos comenzar rápidamente a escribir estilos bizarros o innecesariamente complicados. Para BEM, hay un montón de reglas definidas por los programadores que lo usan para evitar las trampas.
A. Usar nombres únicos para bloques (clases CSS).
B. NO use selectores de ID, ni selectores de etiqueta HTML / base en cascada (childs) (para todo lo que podamos definir la clase CSS).
Eche un vistazo, simplemente es mejor usar selectores como
.score-en-progreso
en lugar de:
# scoreboard> li> b + span
C. Prefijo espacio de nombres. ¿Podemos también usar algunos prefijos? ¡Ciertamente!
Por ejemplo, para los modificadores podemos usar 'is-' o 'has-':
.is-active {} 
.is-hover {} 
.is-dragged {}
Para que los selectores trabajen con JavaScript (para referirse en el código JS) podemos agregar el prefijo 'js-':
.js-sortable {} 
.js-is-active {} 
.js-drag-and-drop {}
Para los ayudantes => 'h-', para los diseños => 'l-', etc.
tipos-bem-prefijos
D. No encadene elementos BEM, así que si nuestra clase se ve así:
.form__row__input
hay algo mal. Es mejor vincular "nietos" directamente al bloque, o crear un bloque separado para ellos.
En BEM, creamos nuestro propio espacio de nombres virtual para elementos específicos (dentro del bloque), y así evitamos conflictos (por ejemplo: .nav__item {} y .menu__item {}, y NO .item {}).
Pero…
E. Nota sobre anidación. Se trata de un anidaje sensato de estilos, sobre todo, NO demasiado profundo.
Ejemplo - MALO, no hagas eso:
1
2
3
4
5
6
.person {}
.person__head {}
.person__head__face {}
.person__head__face__eye {}
.person__head__face__eye__pupil {}
// etc ...
Ejemplo - BUENO:
1
2
3
4
5
6
.person {}
.person__head {}
.person__face {}
.person__eye {}
.person__pupil {}
// etc ...
Es mejor si el subrayado doble aparece una vez en el nombre del selector. Así que escribimos:
Bloque__Elemento – Modificador
Y NO:
Block__Element__Element – ​​Modifier
Por ejemplo, si tenemos un formulario 'search-form', y en él un div 'search-form__content', que contiene entradas, las clases CSS para las entradas se pueden escribir de dos maneras:
NO ESCRIBEMOS
1
2
// bad
search-form__content__input
PERO
1
2
// good
search-form__input
O
1
2
// also good
search-form__content-input
Ambas versiones son correctas, recomendadas por la documentación de BEM.
Echa un vistazo a otras muestras.
Ejemplo - EVITA esto:
1
2
3
4
5
6
7
8
9
10
11
12
<!--Bad-->
<div class="c-card">
  <div class="c-card__header">
    <!-- Grandchild -->
    <h2 class="c-card__header__title">Title text here</h2>
  </div>
  <div class="c-card__body">
    <img class="c-card__body__img" src="pic.png" alt="description">
  ...
</div>
Ahora veamos el mismo código con los selectores corregidos.
Ejemplo - HAGA ESTO:
1
2
3
4
5
6
7
8
9
10
<!--Good-->
<div class="c-card">
  <div class="c-card__header">
    <h2 class="c-card__title">Title text here</h2>
  </div>
  <div class="c-card__body">
    <img class="c-card__img" src="pic.png" alt="description">
  ...
</div>
Eh
Del mismo modo :
1
2
3
4
5
6
7
<div class="block">
  <div class="block__elem1">
    <div class="block__elem2">
      <div class="block__elem3"></div>
    </div>
  </div>
</div>
1
2
3
4
.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}
Y así.
¿Por qué? Construyamos nuestros componentes de una manera inteligente. ¡BEM (u otra convención) es para ayudarnos, no para limitarnos o para complicar cosas simples!
Consejo : para partes de nombre de varios miembros del selector (bloques, elementos o modificadores), simplemente usamos un guión, por ejemplo:
nombre_bloque__ nombre-elemento-my-nombre-modificador-foo-bar
Se recomienda el esquema de nombres, aunque no el único: https://en.bem.info/methodology/naming-convention/#alternative-naming-schemes (BEM se está desarrollando durante más tiempo ;-))
Más sobre buenas prácticas y escollos :
Una palabra sobre mezclas
No siempre necesitamos crear selectores relacionados con bloques. Esto es muy recomendable si pensamos que nuestro bloque será reutilizable.
Pero suponiendo que, por ejemplo, mezclamos los estilos del elemento del menú con el botón, y las clases de "botón" y "activa" de todos nuestros botones se definirán con el mismo código CSS (y eso es suficiente para nosotros en el caso), entonces Podemos crear clases separadas, por eso escribimos:
1
<li class="menu__item button active">
en lugar de por ejemplo:
1
<li class="menu__item menu__button menu__button--active">
Sin embargo, es más probable que los elementos de nuestro proyecto sean muy diferentes entre sí, y luego, por supuesto, nos atenemos a la convención BEM recomendada.
¿Qué pasa con Bootstrap?
Bootstrap Framework no utiliza las convenciones de BEM, por lo que podemos tener miedo al código desagradable cuando mezclamos los estilos de Bootstrap y los nuestros, basados ​​en BEM. Creo que no es un problema!
Usamos las clases de Bootstrap completamente normales, y también aplicamos nuestras propias clases basadas en BEM. A simple vista podemos ver cuáles son de Bootstrap, y cuáles son las nuestras. No debería haber ningún problema. La única buena regla que utilizo en tales casos, es poner las clases de Bootstrap como las primeras en la lista, y las nuestras después, por ejemplo:
1
<div class="col-12 col-lg-6 my-block__wrapper--expanded"> ...
BEM - más recursos