Tag Archives: BEM

Auto-focusing HTML form-fields with smart labels

A thing that I have strived for as long as I can remember is simplicity and ease of use in the work that I do. When working with HTML forms a key manifestation of this philosophy is something as simple as being able to click a label and have focus to be set to the corresponding form-field, i.e. input; textarea; or select element. When I first started doing this, my approach was to use the for attribute of the label element, so that its value matched the id of the form-field, e.g.:

<label for="inputId">Label</label>
<input id="inputId" type="" />

While the above model works from a usability standpoint it fails (in my opinion) from a maintainability standpoint, as you need to either manually or programmatically ensure that the for attribute in the label element matches the id attribute of the corresponding form-field.

… but there’s a better way: If you nest the form-field inside of the label, clicking any part of the element or its descendants will set focus to the form-field without requiring any additional attributes whatsoever. The structure for this is:

<label>Label </label>

… e.g.:

<label>Input <input type="" /></label>

<label>Textarea <textarea></textarea></label>

<label>Select<select></select></label>

From here on it’s really up to you to structure your form-control (i.e. combination of label and form-field) in any way you want. My current model is inspired by the naming conventions of the BEM (Block, Element, Modifier) methodology and looks like, e.g.:

<label class="formcontrol">
    <b class="formcontrol-label">Label</b>
    <input class="formcontrol-input" type="text" />
</label>

Note #1: I don’t use elements for styling (anymore), so the <b> element is really just an inline-element which takes up less characters than, e.g. a <span>.

Advertisements

Using LESS to DRY out your BEM-style CSS and increase maintainability

If writing scalable CSS for your HTML5 projects is of concern to you, chances are that at some point you’ve bumped into the Block, Element, Modifier (or BEM for short) approach. Basically (in my interpretation) what BEM advocates is a model for writing/organizing CSS where:

  • Anything that needs to be styled has a class name, i.e. no styling based on element types.
  • Classes are independent and defined on the same level, so that no styles are dependent of their ancestry, i.e. no class nesting.
  • Related classes are grouped together using a common block name.

The basic CSS for a BEM model is showcased below:

.block {}
.block-element {}
.block--modifier {}

Explanation:

  • The block represents the main component.
  • The block-element (one hyphen) represents a part (sub-element) of the component.
  • The block--modifier (two hyphens) is a modification to the block, e.g. a different background color, layout etc.

(Note: The source BEM approach referenced in the introduction uses “_” (underscores) as separators, but I use “-” (hyphens/dashes) – it’s just a matter of personal preference.)

An HTML structure for the block could look something like this:

<div class="block">
    <div class="block-element"></div>
</div>

<div class="block block--modifier">
    <div class="block-element"></div>
</div>

The example shows two versions of the .block component which both contain a sub-element .block-element, but the second component also contains a .block--modifier which could e.g. display it with a different background color. As all CSS classes start with the same block name it’s easy to see that they are part of the same block.

Now, even though this makes for some pretty understandable and scalable CSS (as blocks and sub-elements will look the same regardless of their context), from a maintainability standpoint, there is a lot of repetition as each style declaration starts with the block name, i.e. the code is not especially DRY, and e.g. changing your mind about the block name will require you to update multiple lines of CSS (3 in the basic example above).

(LESS) CSS pre-processing to the rescue

Luckily, if you’re using the LESS CSS pre-processor (and I’m sure that SASS has the equivalent functionality) there’s an easy way for you to organize your source code which will DRY it out and make it a lot more maintainable: LESS gives us the ability to reference the current selector parent using the “&” (ampersand) character. This means that by using LESS we can reduce our LESS/CSS code to this:

.block {
    &-element {}
    &--modifier {}
}

Explanation: For the -element and --modifier declarations the “&” (current parent selector) will reference the .block name, thus rendering them as .block-element and .block--modifier respectively.

Implementing the above approach means that when you want to change the block name, to e.g. myblock, you only need to change the initial block name (i.e. the first line) and LESS will take care of the rest, i.e.:

.myblock {
    &-element {}
    &--modifier {}
}

…which renders into:

.myblock {}
.myblock-element {}
.myblock--modifier {}

There you go: Scalable, DRY and low-maintenance BEM-style CSS!


Notes

Multi-level sub-elements

Many times your blocks will probably contain multiple levels of nested sub-elements, but you should still keep all of the classes directly related to the main block to ensure that the individual sub-elements parts are as loosely coupled as possible, e.g.:

HTML

<div class="block">
    <div class="block-element">
        <div class="block-element2">
            <div class="block-element3"></div>
        </div>
    </div>

    <div class="block-element4"></div>
</div>

LESS

.block {
    &-element {}
    &-element2 {}
    &-element3 {}
    &-element4 {}
}

Further DRY’ing your LESS

If you’re really (as in really, really) DRY, you will have noticed that there are redundant hyphens/dashes all over the examples, so to get rid of these you can insert additional levels in the LESS code, i.e.:

.block {
    &- {
        &element {}
        &element2 {}
        &element3 {}
        &element4 {}

        &- {
            &modifier {}
            &modifier2 {}
        }
    }
}

… which would leave you with no redundancy in the structure, but perhaps this is taking LESS to extremes. The main priority is that you adapt the functionality to your current situation and do what makes most sense to you – perhaps even on a file-to-file basis.