OOCSS / BEM / SMACSS architettura

8

Ho lavorato su questo articolo per organizzare il mio codice di front-end. Fa riferimento agli articoli su BEM / SMACSS, che a loro volta fanno riferimento ad altri articoli.

Sto davvero cercando di capire quali sono le migliori pratiche ... Ho un paio di giorni per stabilire questo "standard", e poi devo bruciare un progetto di timeline ad alta priorità / alta visibilità / limitato. In quanto tale, mi piacerebbe assicurarmi di iniziare con una base che verrà scalata come fa la mia app.

Dato un componente chiamato segment ... Sto creando pagine che avranno ~ 10% disegments per pagina. Ogni segment condividerà la stessa classe base. Tuttavia, alcuni segments avranno su di essi dei modificatori (colori di sfondo diversi). Inoltre, gli elementi all'interno di ogni blocco (nell'approccio BEM) avranno anche i modificatori. Per dimostrare, ecco una semplice implementazione (con solo un singolo elemento arrow , mentre il mio sito completo avrà 4-5 elementi in ogni segment ):

.segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}
.segment__arrow--orange {
    @extend .segment__arrow;
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow--white {
    @extend .segment__arrow;
    background-image: url('/images/arrow_white.png');
}

Quindi questo è l'approccio a una sola classe:

<div class="segment__arrow--white"> ... </div>

In alternativa, potrei seguire l'approccio multi-classe:

.segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}
.segment__arrow--orange {
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow--white {
    background-image: url('/images/arrow_white.png');
}

Dove il mio markup sarebbe:

<div class="segment__arrow segment__arrow--white"> ... </div>

Terzo, potrei fare:

.segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}
.segment__arrow.orange {
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow.white {
    background-image: url('/images/arrow_white.png');
}

E poi la mia classe def sarebbe

<div class="segment__arrow orange"> ... </div>

Forse anche namespacing orange con qualcosa come sa_orange per evitare selettori allentati.

Il risultato finale che sto cercando è meno codice / più facile da mantenere (il che probabilmente esclude l'approccio a classe singola (opzione 1), come descritto in questo ottimo articolo su architettura scalabile L'approccio multi-classe (opzione 2) risulta molto verboso (specialmente nel mio HTML), ma è estremamente esplicito. Il terzo usa un approccio multi-classe, ma non usa i modificatori con namespace (come .segment__arrow), quindi è un po 'meno verboso (ma anche un potenziale meno esplicito e più elevato per le collisioni).

Qualcuno con esperienza del mondo reale con questa roba ha qualche feedback sul modo migliore per avvicinarsi a questo?

    
posta Scott Silvi 26.12.2013 - 23:04
fonte

2 risposte

8

Da molto tempo utilizzo e raccomando l'approccio esplicito multi-classe (il secondo esempio) in quanto è il più universale, manutenibile e coerente. Qui proverò a supportare questo reclamo.

Singolo classe

Questo approccio ha un grosso problema quando ci sono due o più categorie di modificatori. Ad esempio un .button con modificatori piccolo , grande , enorme per dimensioni e primario , successo , informazioni e avviso per "colore". Oltre alle solite 7 (= 3 + 4) classi si devono creare tutte e 12 le combinazioni:

.button--small--primary
.button--small--success
.button--small--info
…

Finora un po 'scomodo ma non un disastro.

Un altro fastidio - uno più grande - è che l'ordine corretto "taglia prima, colore secondo" deve essere usato e quindi ricordato (e ben documentato).

Il peggio è quando JavaScript è coinvolto. Vuoi cambiare il "colore" di questo pulsante ma mantieni la dimensione attuale? Analizza l'attributo della classe! Vuoi solo rimuovere il modificatore successo ? Analizza l'attributo della classe!

Conta che ad es. Bootstrap ha 7 "colori", 4 dimensioni e stati attivi / disabilitati; per cui devono essere dichiarate 119 (= 13 + [7 * 4 + 7 * 2 + 4 * 2] + 7 * 4 * 2) classi per mantenere un approccio a una sola classe! Questo è il grande problema.

Explicit multi-class richiederebbe solo 13 classi (una per ogni modificatore). L'ordine sarebbe arbitrario. Infine, aggiungendo, rimuovendo e modificandone uno mentre si preservano gli altri, in jQuery sembrerebbe:

$('#login-button').removeClass('button--primary').addClass('button--success');

Collegamento multi-classe

In primo luogo, come hai detto, c'è un potenziale per le collisioni - una cosa negativa da sola.

In secondo luogo, ciò che significa anche che il .segment__arrow.orange ha una specificità più elevata e non può essere sovrascritto con un selettore di classe singolo. Questo è spesso in questione quando un elemento è ad es. non solo un pulsante grande ma anche per es. un pulsante di accesso . Il suo codice dovrebbe essere:

<a href="#" class="button large primary login__button">Log in</a>

Si potrebbe desiderare di avere un riempimento sinistro e destro più grande sul pulsante di accesso, ma mantenere l'altezza di grande . Ciò comporterebbe selettori sempre più specifici che ci porterebbero alla particolarità dell'inferno - un luogo in cui OOCSS dovrebbe salvarci.

È evidente che ciò non accadrebbe nell'approccio esplicito multi-classe .

Multi-classe esplicita

L'unico problema (per quanto ne so) di questo è che ci sono alcune classi a volte piuttosto lunghe nel markup. Lo ammetto.

Consentitemi di notare che questa è solo una questione di gusti dello sviluppatore in quanto ha un effetto trascurabile (per niente) alla performance. La compressione standard si prenderà cura di questo.

Detto questo, usare un buon IDE aiuterà a scrivere questi (sì, lo so, sembrerà ancora un po 'ridicolo).

Da una parte, direi, vedere classi così lunghe costringe a pensare di più alla struttura; per esempio. se non sarebbe meglio introdurre un nuovo componente (riusabile) invece di annidarlo in qualcos'altro.

    
risposta data 31.03.2014 - 20:12
fonte
0

In questo momento sto discutendo con i miei compagni di discussione su questo problema di classe singola / multipla

qui ci sono alcune delle mie personalmente viste basate sulla best practice

Best Practice

  • html dichiara gli elementi
  • Il rendering dei controlli CSS

Single Class segue sempre la Best Practice

con ulteriori vantaggi di mantenimento, con buoni nomi che può raggiungere

  • la modifica dello stile non richiede l'aggiornamento html * (vedi demo)

  • stile di blocco in html (avrai lo stile giusto o niente)

Demo

@mixin segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}

.segment__arrow--type1 {
    @include segment__arrow;
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow--type2 {
    @include segment__arrow;
    background-image: url('/images/arrow_white.png');
}

@mixin include è migliore di @extend

  1. ha il controllo dell'ordine del codice nel css finale
  2. dimensioni più piccole nella versione di gzip

e uguale a @extend, può essere riutilizzato e può sostituire la multi classe in HTML

con @mixin, otterrai ulteriore flessibilità

@mixin segment__arrow--type1 {
    @include segment__arrow;
    background-image: url('/images/arrow_orange.png');
}
@mixin segment__arrow--type2 {
    @include segment__arrow;
    background-image: url('/images/arrow_white.png');
}
.segment__margic-arrow {
    @include screen(mobile) {
       @include segment__arrow--type1
    }
    @include screen(desktop) {
       @include segment__arrow--type2
    }
}

Per javascript usa

regole dello stato di smacss

Svantaggio di una singola classe

uno e solo:

dimensioni più grandi dei file CSS, MA puoi sempre ottimizzare facilmente i CSS in base alle sezioni o ai componenti del sito web nella pagina

    
risposta data 11.07.2017 - 02:33
fonte

Leggi altre domande sui tag