I’ve implemented North on a couple of large builds (largely because of my dissatisfaction with BEM naming conventions) and have found that it really cuts down on the amount of code both written and output. A major contributing factor to this is the use of aspects to pivot layouts and components however it’s not clear what the best practice is for pivoting elements within an aspect of a layout or a component.
The problem (using the layout at https://github.com/north/north#css-naming-conventions as an example) is that if I have the following layout;
%_article--media {
float: left;
width: 30%;
}
%_article--body {
float: right;
width: 70%;
}
%_article--media--BIG-MEDIA {
width: 50%;
}
%_article--body--BIG-MEDIA {
width: 50%;
}
._article {
&--media {
@extend %_article--media;
}
&--body {
@extend %_article--body;
}
}
._article--BIG-MEDIA {
._article--media {
@extend %_article--media;
}
._article--body {
@extend %_article--body;
}
}
then the elements within the aspect are not taking advantage of the ampersand and as such require needless repetition and also more refactoring if the class changes.
You could nest the elements within the aspect as you would with the base component or layout;
._article--BIG-MEDIA {
&--media {
@extend %_article--media;
}
&--body {
@extend %_article--body;
}
}
but it makes the code less portable or scaleable because when you need to convert from one aspect to another you have to change the classes of all the elements rather than just the one parent class in the markup.
I’ve come up with a number of solutions but I was wondering which would be considered best practice or whether there is a better solution that I cannot see. I also wonder if a note on the best practice should be added to the documentation.
- You could put the aspect inside the base layout:
._article {
&--media {
@extend %_article--media;
}
&--body {
@extend %_article--body;
}
&--BIG-MEDIA &--media {
@extend %_article--media--BIG-MEDIA;
}
&--BIG-MEDIA &--body {
@extend %_article--body--BIG-MEDIA;
}
}
- You could store the layout class in a variable which you could use in the extends as well.
$layout-class: _article;
%#{$layout-class}--media {
float: left;
width: 30%;
}
%#{$layout-class}--body {
float: right;
width: 70%;
}
%#{$layout-class}--media--BIG-MEDIA {
width: 50%;
}
%#{$layout-class}--body--BIG-MEDIA {
width: 50%;
}
.#{$layout-class} {
&--media {
@extend %#{$layout-class}--media;
}
&--body {
@extend %#{$layout-class}--body;
}
}
.#{$layout-class}--BIG-MEDIA {
.#{$layout-class}--media {
@extend %#{$layout-class}--media--BIG-MEDIA
}
.#{$layout-class}--body {
@extend %#{$layout-class}--body--BIG-MEDIA
}
}
- You could add the aspect class to the extends using an @at-root directive.
$layout-class: _article;
%#{$layout-class}--media {
float: left;
width: 30%;
@at-root .#{$layout-class}--BIG-MEDIA & {
width: 50%;
}
}
%#{$layout-class}--body {
float: right;
width: 70%;
@at-root .#{$layout-class}--BIG-MEDIA & {
width: 50%;
}
}
.#{$layout-class} {
&--media {
@extend %#{$layout-class}--media;
}
&--body {
@extend %#{$layout-class}--body;
}
}
I’ve implemented North on a couple of large builds (largely because of my dissatisfaction with BEM naming conventions) and have found that it really cuts down on the amount of code both written and output. A major contributing factor to this is the use of aspects to pivot layouts and components however it’s not clear what the best practice is for pivoting elements within an aspect of a layout or a component.
The problem (using the layout at https://github.com/north/north#css-naming-conventions as an example) is that if I have the following layout;
then the elements within the aspect are not taking advantage of the ampersand and as such require needless repetition and also more refactoring if the class changes.
You could nest the elements within the aspect as you would with the base component or layout;
but it makes the code less portable or scaleable because when you need to convert from one aspect to another you have to change the classes of all the elements rather than just the one parent class in the markup.
I’ve come up with a number of solutions but I was wondering which would be considered best practice or whether there is a better solution that I cannot see. I also wonder if a note on the best practice should be added to the documentation.