L
L
larfeus2020-12-21 00:06:08
css
larfeus, 2020-12-21 00:06:08

BEM. How to implement nesting of blocks of the same type into each other without overlapping styles?

There is a component:

<table class="table">
    <tbody class="table__body">
        <tr class="table__row">
            <td class="table__cell">
                ...
            </td>
        </tr>
    </tbody>
</table>


A table can have several theming options:

.table {
    &__body { }
    &__row { }
    &__cell { }
    
    &_dark &__cell {
        background: black;
        color: white;
    }
}


Suppose within the framework of the application implementation there is a nesting of one table into another. This can easily happen if there is a modal window (with an activator button) in one of the cells of the "parent table".

<td class="table__cell">
    <modal title="Редактировать">
        <table class="table">
            <tbody class="table__body">
                <tr class="table__row">
                    <td class="table__cell">
                        ...
                    </td>
                </tr>
            </tbody>
        </table>
    </modal>
</td>


We need the table on the first level to have a dark theme, and in modal windows, a standard one. But due to the prioritization of the selectors within the second table, all cells will be the same with the `dark` theme.

OK.

Option 1: Use more specific style selectors.

.table {
    ...

    &_dark > &__body > &__row > &__cell {
        background: black;
        color: white;
    }
}


What if the block contains 10 or more elements? What if the layout changes? The footcloth in styles turns out so-so. The decision is obviously bad and crutch.

Option 2. Use an explicit "default" theme.

<table class="table table_dark">
    ...
    <td class="table__cell">
        ...
        <table class="table table_default">
            ...
        </table>
    </td>
</table>


.table {
    &_default {
        &__body { }
        &__row { }
        &__cell { }
    }

    &_dark {
        &__body { }
        &__row { }
        &__cell {
            background: black;
            color: white;
        }
    }
}


And if the theme consists of several parameters (color, size, presence of borders, font, etc.)? Styles are more structured than in option 1. But:

- Firstly, the probability of an error increases something somewhere to forget/lose/redefine. Especially when working together on the code of several developers.
- Secondly, getting rid of code duplication, we get a footcloth in styles like this:

&_default &__body,
&_dark &__body {
    ...
}

&_default &__cell,
&_small &__cell {
    ...
}


Option 3. Do not allow nesting of elements of the same type.

On really big projects, it is rather difficult to avoid such situations. IMHO, it puts front-end development in a rather rigid framework in terms of layout and component architecture.

If we talk about specific solutions, for example, on vuejs, then this is vue-portal / vue-teleport. But in fact, the problem can arise not only with modal windows, which are given in the example as the most striking example. For card-inside-card use of the portal is not justified.

___________

How do you solve the problem?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
B
BigSmoke, 2020-12-21
@BigSmoke

Probably it should be done something like this:
Styles that do not change are written to a block or element
Styles that are changed are written to modifiers
All blocks and elements are always used with modifiers
It will turn out something like this https://jsfiddle.net/termitkin /as0vLjo1/

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question