CSS/SCSS — многоразовый микс для пользовательских стилей атрибутов

#javascript #css #sass #scss-mixins

Вопрос:

Я создаю многоразовый всплывающий компонент со стрелкой, расположенной рядом с полем. Мне интересно, есть ли способ использовать миксин, чтобы сделать стиль размещения проще/аккуратнее?

 .dialog {
    ...

    amp;[data-arrow-placement^='top'] {
        [data-arrow] {
            bottom: -12px;
        }
    }

    amp;[data-arrow-placement^='bottom'] {
        [data-arrow] {
            top: -12px;
        }
    }

    amp;[data-arrow-placement^='left'] {
        [data-arrow] {
            right: -12px;
        }
    }

    amp;[data-arrow-placement^='bottom-right'] {
        [data-arrow] {
            left: -12px;
            top: -12px;
        }
    }
}
 

Изначально у меня была цепочка @if, которая использовалась, однако, похоже, что это добавит больше сложности, чем требуется.

Ответ №1:

В зависимости от того, что еще вы хотите сделать с этим селектором, я бы сделал либо так:

 @mixin arrowPlacement($placement) {
    amp;[data-arrow-placement^="#{$placement}"] {
        [data-arrow] {
            @content;
        }
    }
}

.dialog {
    $arrowPosition: -12px;
    
    @include arrowPlacement(top) {
        bottom: $arrowPosition;
    };
    
    @include arrowPlacement(bottom) {
        top: $arrowPosition;
    };
    
    @include arrowPlacement(left) {
        right: $arrowPosition;
    };
    
    @include arrowPlacement(bottom-right) {
        left: $arrowPosition;
        top: $arrowPosition;
    };
}
 

Или вот так (вы даже можете добавить @content , если потребуется):

 @mixin arrowPlacement($placement, $position, $properties...) {
    amp;[data-arrow-placement^="#{$placement}"] {
        [data-arrow] {
            @each $property in $properties {
              #{$property}: $position;
            }
        }
    }
}

.dialog {
    $arrowPosition: -12px;

    @include arrowPlacement(top, $arrowPosition, bottom);
    @include arrowPlacement(bottom, $arrowPosition, top);
    @include arrowPlacement(left, $arrowPosition, right);
    @include arrowPlacement(bottom-right, $arrowPosition, left, top);
}
 

И если вы не планируете повторно использовать миксин, вы можете использовать значение -12px позиции напрямую, а не передавать его в качестве параметра:

 @mixin arrowPlacement2($placement, $properties...) {
    amp;[data-arrow-placement^="#{$placement}"] {
        [data-arrow] {
            @each $property in $properties {
              #{$property}: -12px;
            }
        }
    }
}

.dialog {
    @include arrowPlacement2(top, bottom);
    @include arrowPlacement2(bottom, top);
    @include arrowPlacement2(left, right);
    @include arrowPlacement2(bottom-right, left, top);
}
 

Это argument list (...) позволит вам передать столько свойств, сколько вы захотите.

Комментарии:

1. Я выбрал что-то вроде варианта 1. Все чисто и просто, спасибо!

Ответ №2:

Как насчет чего-нибудь в этом роде?:

 @mixin arrow($placement,$position,$other:'') {
    amp;[data-arrow-placement^='#{$placement}'] {
        [data-arrow] {
            #{$position}: -12px;
            @if $other != '' {
              #{$other}: -12px;
            }
        }
    }
}

.dialog {
  @include arrow('top','bottom');
  @include arrow('bottom','top');
  @include arrow('left','right');
  @include arrow('bottom-right','left','top');
}