Css Less Mixin не выводит весь код медиа-запроса

У меня есть миксин - он немного сложнее, чем все, что я делал раньше, так что теперь я столкнулся с проблемой, с которой не могу разобраться. Проблема в том, что по умолчанию никогда не создается. Я также явно добавил мобильный первый медиа-запрос, но он тоже не работает.

.fluid-margin(@top; @right; @bottom; @left;)
{
    .make-margin(@xs-gutter-width);

    @media @sm-screen {
        .make-margin(@sm-gutter-width);
    }
    @media @md-screen {
        .make-margin(@md-gutter-width);
    }
    @media @lg-screen {
        .make-margin(@lg-gutter-width);
    }

    .make-margin(@scale)
    {
        .make-margin(@scale) when (@top > 0)
        {
            margin-top:@scale * @top;
        }
        .make-margin(@scale) when (@right > 0)
        {
            margin-right:@scale * @right;
        }
        .make-margin(@scale) when (@bottom > 0)
        {
            margin-bottom:@scale * @bottom;
        }
        .make-margin(@scale) when (@left > 0)
        {
            margin-left:@scale * @left;
        }
    }
}

Выход

.list-section-header {
  overflow: hidden;
  text-align: center;
}
@media only screen and (min-width:600px) and (max-width:899px) {
  .list-section-header {
    margin-top: 2.25rem;
    margin-bottom: 2.25rem;
  }
}
@media only screen and (min-width:900px) and (max-width:1199px) {
  .list-section-header {
    margin-top: 2.25rem;
    margin-bottom: 2.25rem;
  }
}
@media only screen and (min-width:1200px) and (max-width:1280px) {
  .list-section-header {
    margin-top: 3rem;
    margin-bottom: 3rem;
  }

Вызывая класс

.fluid-margin(1.5rem; 0; 1.5rem; 0);

1 ответ

Решение

Поведение Объяснение:

В вашем смешанном коде есть один внешний (родительский) .make-margin(@scale) mixin, в котором нет ничего, кроме нескольких охраняемых mixins. Обычно, когда вызывается миксин, выводятся только те свойства, которые в нем присутствуют или те, которые являются частью каких-либо блоков селектора. Здесь нечего выводить, когда миксин вызывается впервые, так как содержимое родительского миксина - это только дополнительные миксины, как указано ранее.

Когда миксин вызывается впервые (вызов настроек по умолчанию), он охватывает все содержимое .make-margin() родительский миксин в .fluid-margin() mixin и тем самым выставляет все свои дочерние mixins. Из-за этого воздействия, когда вы вызываете его во второй (и последующие) раз из других медиазапросов, компилятор может обрабатывать их и выдавать требуемый результат.

По сути, первый вызов mixin (по умолчанию) не делает ничего, кроме предоставления его содержимого области видимости вызывающей стороны.


Проверка поведения:

Приведенное выше утверждение можно проверить, выполнив одно из следующих действий.

  1. Закомментируйте первый вызов mixin (тот, который выводит настройки по умолчанию), и вы заметите, что даже другие медиа-запросы не производят никакого вывода. Это потому, что охраняемые дочерние миксины не видны .fluid-margin(),
  2. Повторите смешанный вызов по умолчанию (.make-margin(@xs-gutter-width);) непосредственно под первым, и вы заметите, что он производит вывод по умолчанию также потому, что дочерние миксины теперь подвергаются .fluid-margin(),
  3. Добавить еще .make-margin(@scale) линия внутри родителя .make-margin() Mixin. Это также приведет к выводу по умолчанию, потому что дочерние миксины находятся в той же области, и, следовательно, вызов миксина может их достичь.

Возможные решения:

Вариант 1: избегать родителя .make-margin(@scale) гнездится полностью так, как не нужно. Вы можете напрямую выставить его дочерние миксины .fluid-margin Mixin. Образец этого подхода можно найти здесь.

.make-margin(@scale) when (@top > 0){
    margin-top: @scale * @top;
}
.make-margin(@scale) when (@right > 0){
    margin-right: @scale * @right;
}
.make-margin(@scale) when (@bottom > 0){
    margin-bottom: @scale * @bottom;
}
.make-margin(@scale) when (@left > 0){
    margin-left: @scale * @left;
}

Вариант 2: вместо использования другого определения mixin в родительском, просто используйте & (родительский селектор) для охранников, как показано ниже. Здесь & будет относиться к селектору, из которого был вызван миксин. Так как свойства, указанные в & будет частью блока селектора, а также потому, что к нему не прикреплены круглые скобки, он все равно будет производить вывод. Образец этого подхода можно найти здесь.

.make-margin(@scale)
{
    & when (@top > 0){
        margin-top: @scale * @top;
    }
    & when (@right > 0){
        margin-right: @scale * @right;
    }
    & when (@bottom > 0){
        margin-bottom: @scale * @bottom;
    }
    & when (@left > 0){
        margin-left: @scale * @left;
    }
}

Второй вариант намного чище (как вы уже упоминали в комментариях).

Другие вопросы по тегам