css - BEM approach for an element than can belong and look different depending on the Block? -


let's have styled checkbox (think material design, there bit going on achieve desired checkbox style). block responsible modifying parent-dependent child block?

example component - checkbox

so have following:

<div class="checkbox">     <label class="checkbox__label">         <input class="checkbox__input" type="checkbox" checked=true />         <span class="checkbox__icon glyphicon glyphicon-ok"></span>         <span class="checkbox__text">{label}</span>     </label> </div> 

i style each element within block base checkbox. within context of application, checkbox block can live in many other blocks (with own bem structures).

example of other blocks

the checkbox have difference appearance when within "compact panel":

<div class="panel panel--compact">     <p>disclaimer.. [text]</p>     <checkbox label="i agree" />  </div>  

option 1 - parent "knows" child

so.. should compact panel "aware" of various children blocks, , style them, so:

// checkbox.scss  .checkbox {     margin: 15px;     // .. other }   // panel.scss .panel {     &.panel--compact {         margin: 0;         padding: 2px;     }     &.panel--compact .checkbox {         margin: 0;         padding: 1px;     } } 

option 2 - child "knows" parent

or, panel has 0 awareness, , checkbox checks parent scope.

// checkbox.scss  .checkbox {     margin: 15px;     padding: 15px;     // .. other } .panel.panel--compact .checkbox {     margin: 0;     padding: 1px; }   // panel.scss .panel {     &.panel--compact {         margin: 0;         padding: 2px;     } } 

option 3 - ?

maybe there other options.

usually bem if look different, are different.

usually.

there number of different choices handling context , state bem. each has different pros , cons, use depend heavily on use case.

the first option i'll mention use descendant selectors. you've identified choice, , running usual problem of "where code belong?"


for following examples, i'm going rely on less syntax, make easier me demonstrate relationships in code.


descendant selector

if you're going use descendant selector, recommend code grouped child block.

widget.less
.widget {   &__container {     ...   }   ... } 
checkbox.less
.checkbox {   &__label {     ...   }   ...    // using inversion override checkbox styles in widget   // render `.widget .checkbox` instead of   // `.checkbox .widget` due `&` placement   .widget & {   } } 

the reason recommend associating styles inner block because styles affect checkbox, , cascade order important.

if styles associated parent, reordering parent styles relative child styles adversely affect how styles render.

consider inclusion order:

site.less
@import 'widget'; @import 'checkbox'; 

if styles part of widget, overridden selector of equal specificity in checkbox.less.

modifiers

i recommend using modifiers state. don't consider position or context "state", modifiers may not appropriate. additionally, multiple modifiers on same element can difficult reason , therefor difficult style.

assuming you're not using modifier on checkbox block, may simpler add modifier case it's used in panel.

.checkbox {   &__label {     ...defaults...   }   ...defaults...    &--alt {     &__label {       ...overrides...     }     ...overrides...   } } 

of course, requires markup updated particular case it's used in panel, opens using checkbox same styles elsewhere.

different selector

i'm going reiterate first point: if look different are different.

this doesn't mean have start scratch on checkbox. bem allows object oriented styles. come new name, , extend* checkbox:

checkbox.less
.checkbox {   &__label {     ...   }   ... } 
checkbox-2.less
@import (reference) 'checkbox'; .checkbox-2 {   .checkbox;    &__label {     ...overrides...   }   ...overrides... } 

* in less i'm using mixin it's better suited toward extending , overriding styles using :extend feature of language. feel free use :extend feature, aware selector order matter.

refactor need away

sometimes run cases want use descendant selector or modifier because need bump block positioning purposes in container.

in these cases, find the container itself should changed. can tell it's container when need update child have different:

  • margins
  • padding
  • position
  • top, right, bottom, left
  • width
  • height
  • flex

refactoring comes other challenges, end using container divs normalize insertion region blocks contain other blocks; ymmv.


tl;dr: should pick?

can (reasonably) update markup?

yes: if can update markup use different classes, i'd recommend extending checkbox block new block. naming things hard though, sure document 1 somewhere.

no: if can't update classes, using modifiers wouldn't great choice either. i'd recommend skipping one, , falling ol' descendant selector. in bem really want avoid descendant selectors, they're right tool job.


Comments

Popular posts from this blog

javascript - How to get current YouTube IDs via iMacros? -

c# - Maintaining a program folder in program files out of date? -

emulation - Android map show my location didn't work -