Vamos ahora a ver lo mas importante de todo el módulo. ¡Como organizar nuestras clases CSS!. Antes de empezar puede leer este artículo que habla sobre la importancia de una arquitectura CSS: ¿Por qué nos olvidamos de la Arquitectura CSS?
Cuando nos enfrentamos a proyectos grandes, puede que nuestros compañeros no entiendan nuestras líneas de código, para eso se crearon las arquitecturas de CSS.
Los objetivos son:
Buenas prácticas
Como arquitectura CSS vamos a seguir durante todo el curso una llamada BEM.
Lo primero es identificar los bloques de nuestra página. Esos bloque son como componentes u objetos que la página. En las siguientes imágenes podemos ver ejemplos de bloques.
Vemos que un bloque puede o no tener dentro otro bloque. En bloque "head" tiene dentro muchos bloques.
Como los bloques pueden ser muy complejos, cada bloque puede tener si lo necesita de "elementos". Veamos un ejemplo:
El componentes de "Tab" tiene 4 pestañas.
Por último nos quedarían los modificadores que luego veremos.
Así que BEM significa lo siguiente:
Así que vamos a tener clases CSS que serán de tipo Bloque, de tipo Elemento o de tipo Modificador. Pasemos a ver un ejemplo.
Imaginar el siguiente panel:
Su HTML sería una cosa así:
<div>
<div>Cabecera</div>
<div>
<p>Contenido</p>
<p>Mas contenido</p>
</div>
</div>
Todo ese HTML forma el bloque "Panel" que está compuesto dos por elementos "Titulo" y "Contenido". Así que las clases CSS van a ser las siguientes
<div class="c-panel">
<div class="c-panel__titulo">Cabecera</div>
<div class="c-panel__contenido">
<p>Contenido</p>
<p>Mas contenido</p>
</div>
</div>
Como vemos el nombre de la clase CSS de un bloques es como el nombre del bloque con el prefijo "c-". Mientras que el nombre de un elemento es como el nombre del elemento prefijado con el nombre del bloque y "__". Es importante recordar que son necesarias las "__". No se puede poner otra cosa que no sea eso.
¿Que ocurre con el tag <p>. No forma parte del panel . Es otro bloque que podemos meter dentro del panel pero no forma parte del bloque "panel".
Veamos otro ejemplo con un botón:
Solo hay un bloque llamado "c-boton" y no hay elementos.
<div class="c-boton">Mas información</div>
Por último nos faltan los modificadores. Imaginar que queremos que el panel pueda tener varios colores:
¿Como modificamos el CSS para incluir esos nuevos colores? Pues con un modificador.
<div class="c-panel c-panel--warning">
<div class="c-panel__titulo c-panel__titulo--warning">Cabecera</div>
<div class="c-panel__contenido c-panel__contenido--warning">
<p>Contenido</p>
<p>Mas contenido</p>
</div>
</div>
Vemos que hemos añadido a todas las clases una nueva clase que se llama igual a la que ya hay pero acabada "–warning". Pues bien , esa nueva clases, es el modificador. El modificador realmente se llama "warning" pero para que se sepamos que es un modificador y para saber a que bloque o elemento pertenece se separa por "–" (dos guiones) al nombre del bloque o elemento.
Así que pasemos ahora a ver una serie de reglas:
Hemos visto que los bloques empiezan por "c-" , eso es porque son como componentes visuales. Veamos los prefijos que pueden haber:
Dentro de los modificadores hay de otro tipo que es el modificador global que empieza por g– (la letra g y dos guiones). Es un modificador que se puede usar con cualquier componente. Se suele usar para definir cosas como los margenes, los paddings, etc. De esa forma no es necesario tener el mismo modificador en cada componente.
Veamos ahora un ejemplo un poco mas complejo
<body class="c-body">
<div class="l-page">
<div class="l-page__header">
<img class="c-logo">
<div class="c-menu">
<div class="c-menu__item ">Nuevo</div>
<div class="c-menu__item menu__item--active">Editar</div>
<div class="c-menu__item menu__item--disable">Borrar</div>
</div>
</div>
<div class="l-page__body">
<form class="c-form g--margin-4 g--margin-bottom-6">
<input class="c-input" >
<input class="c-input" >
<input class="c-input" >
<button class="c-button c-button--primary c-button--normal">Guardar</button>
</form>
</div>
<div class="l-page__footer">
<div class="l-horizontal">
<img class="c-social" src="facebook.png">
<img class="c-social" src="youtube.png">
<img class="c-social" src="instagram.png">
<img class="c-social" src="twitter.png">
</div>
</div>
</div>
</body>
Están los siguientes bloques de tipo componentes y sus elementos:
Luego están los Layouts
Están los modificadores de cada componente o elemento
Y por último están los modificadores globales:
Sobre BEM hay mucha documentación, aquí os dejo varios links para que podáis entenderlo mejor:
Crea un componente que tenga lo siguiente:
La imagen es esta: monitor.webp
Los caracteres de la estrella y el camión son:
<c-articulo nombre="Monitor Acer Nitro KG241YX3BIP 23.8' FHD 200Hz VA FreeSync Premium HDR10" urlImagen="https://logongas.es/lib/exe/fetch.php?cache=&media=clase:daw:diw:1eval:monitor.webp" [precioActual]="89.99" [precioAnterior]="99.99" [valoracion]="4.6" [numeroOpiniones]="1472" [fechaEntrega]="fechaEntrega" [precioEnvio]="0.00" [otrosEnvios]="true" />
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {CommonModule} from '@angular/common';
@Component({
selector: 'c-articulo',
imports: [CommonModule],
templateUrl: './c-articulo.html',
styleUrl: './c-articulo.scss'
})
export class CArticulo {
@Input() nombre:string="";
@Input() urlImagen:string="";
@Input() precioActual:number=0;
@Input() precioAnterior:number=0;
@Input() valoracion:number=0;
@Input() numeroOpiniones:number=0;
@Input() fechaEntrega:Date=new Date();
@Input() precioEnvio:number=0;
@Input() otrosEnvios:boolean=false;
}
<div class="c-articulo">
<img class="c-articulo__image" src="{{urlImagen}}" >
<h3 class="c-articulo__title">{{nombre}}</h3>
<p class="g--margin-vertical-2">
<span class="c-articulo__precio c-articulo__precio--actual">{{precioActual | currency}}</span>
<span class="c-articulo__precio c-articulo__precio--anterior">{{precioAnterior | currency}}</span>
</p>
<p>
<span class="c-articulo__valoracion">{{valoracion}}/5</span>
<span class="g--font-size-4">⭐</span>
<span class="c-articulo__opiniones">{{numeroOpiniones}} opiniones</span>
</p>
<p class="">
🚚
<span class="c-articulo__entrega c-articulo__entrega--positivo">{{precioEnvio | currency}}</span>
<span class="c-articulo__entrega c-articulo__entrega--negativo">{{fechaEntrega| date:'shortDate'}}</span>
</p>
<p class="c-articulo__otras-opciones g--margin-top-2">
Otras opciones disponibles
</p>
</div>
.c-articulo {
font-family: "Open Sans", Arial, sans-serif;
width: 197px;
color: #333;
&__title {
font-size: 14px;
font-weight: 500;
color: #333;
}
&__precio {
&--actual {
font-size: 17px;
font-weight: 700;
color: #bf0019;
}
&--anterior {
font-size: 14px;
color: #6e6e6e;
text-decoration: line-through;
}
&-envio {
color: #ff7a00;
font-weight: 600;
}
}
&__valoracion {
font-size: 13px;
font-weight: 600;
color: #333;
}
&__opiniones {
color: #333333;
font-size: 13px;
}
&__entrega {
font-size: 13px;
font-weight: 700;
&--positivo {
color: #008000;
}
&--negativo {
color: #333333;
}
}
&__otras-opciones {
font-size: 13px;
color: #777;
font-weight: 600;
}
}
Modifica ahora el componente para que