Свернуть макет строки в столбец с меньшей шириной без потери верхнего поля для предыдущего элемента

#html #css #sass

#HTML #css #sass

Вопрос:

Цели

Я пытаюсь выполнить следующее:

  1. Когда экран достаточно широк, элементы .firstItem (красный) и .lastItem (синий), ширина которых заранее неизвестна, находятся в левой и правой части родительского .layout элемента соответственно.

  1. Когда экран становится уже, а расстояние по горизонтали между элементами уменьшается $minimalHorizontalSpaceBetweenItems , макет сворачивается в столбец, но по .firstItem -прежнему выравнивается по левому и правому краю .lastItem :

  1. Вертикальное пространство между элементами $verticalSpaceBetweenItems не должно влиять на макет в конфигурации с одной строкой.

  2. Приведенное ниже правило CSS для желтого .preceedingElement блока выше .firstItem и .lastItem должно работать:

 .preceedingElement   .layout {
   margin-top: Npx;
}
  

Базовый MWE

 <div class="preceedingElement"></div>
<div class="layout">
  <div class="firstItem"></div>
  <div class="lastItem"></div>
</div>
  

SCSS:

 .preceedingElement{
  width: 100%;
  height: 30px;
  background: #FAD7A0;
}

@mixin TwoSpacedItemsComposition(
  $minimalHorizontalSpaceBetweenItems: 0,
  $verticalSpaceBetweenItems: 0
) {
  
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  
  margin-top: -$verticalSpaceBetweenItems;
  margin-right: -$minimalHorizontalSpaceBetweenItems;
  
  
  > *{
    margin-top: $verticalSpaceBetweenItems;
    margin-right: $minimalHorizontalSpaceBetweenItems;
    
    amp;:last-child {
      margin-left: auto;
    }
  }
}
  
.layout {
  @include TwoSpacedItemsComposition(
    $minimalHorizontalSpaceBetweenItems: 12px,
    $verticalSpaceBetweenItems: 24px
  )
}

.firstItem {
  width: 200px;
  height: 34px;
  background: #EC7063;
}

.lastItem {
  width: 400px;
  height: 24px;
  background: #7FB3D5;
}
  

Попытка гибкого решения

Ниже SASS mixin реализует все цели, кроме четвертой:

 @mixin TwoSpacedItemsComposition(
  $minimalHorizontalSpaceBetweenItems: 0,
  $verticalSpaceBetweenItems: 0
) {
  
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  
  margin-top: -$verticalSpaceBetweenItems;
  margin-right: -$minimalHorizontalSpaceBetweenItems;
  
  
  > *{
    margin-top: $verticalSpaceBetweenItems;
    margin-right: $minimalHorizontalSpaceBetweenItems;
    
    amp;:last-child {
      margin-left: auto;
    }
  }
}
  

Помехи margin-top: -$verticalSpaceBetweenItems; для родительского и margin-top: $verticalSpaceBetweenItems; дочернего элементов.

🌎 Скрипка JS

Попытка решения сетки

Сетка всегда отображает 2 строки.

 @mixin TwoSpacedItemsComposition(
  $minimalHorizontalSpaceBetweenItems: 0,
  $verticalSpaceBetweenItems: 0
) {

  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, auto));
  grid-gap: $verticalSpaceBetweenItems $verticalSpaceBetweenItems;

  align-items: center;


  >* {

    amp;:first-child {
      justify-self: start;
    }

    amp;:last-child {
      justify-self: end;
    }
 }
  

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

1. 1. Ваш HTML также должен быть в вопросе. (Я понимаю, что это минимально, но вопрос должен содержать весь код, необходимый для воспроизведения проблемы.) 2. Ваше текущее объяснение того, что вы пытаетесь сделать, зависит от того, сможет ли читатель видеть изображение и различать цвета, что не всегда будет правдой. Ссылаться на них как на верхний заголовок во всю ширину, левый столбец и правый столбец было бы понятнее для людей, которые не могут видеть изображение.

2. @BSMP, «Ваш HTML также должен быть в вопросе», — добавил я. Но я не могу использовать скрипку StackOverlow, потому что она не поддерживает препроцессоры css (функциональность mixin требуется в этом вопросе). «Ваше текущее объяснение того, что вы пытаетесь сделать, зависит» — они не являются столбцами в значении «контейнер», «они» могут быть элементами ввода или кнопками. Я буду ссылаться на них по классам CSS.

3. Использование скрипки переполнения стека не является обязательным требованием, это нормально, что вы ее не используете. Пока код находится в вопросе, этого достаточно.

4. @BSMP, понял. Я добавлю HTML-код в свои будущие вопросы.

Ответ №1:

Ваш подход flexbox, похоже, работает отлично… Изменение margin-top: $verticalSpaceBetweenItems; на margin-bottom: $verticalSpaceBetweenItems; должно решить требование № 4, а ваш исходный код flexbox уже решил первые три.

JSFiddle: https://jsfiddle.net/yx689sh4 /

Ответ №2:

Рассматривали ли вы возможность использования процентов для ширины для ваших двух элементов?

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

1. Спасибо за попытку ответа. Пожалуйста, напишите комментарий вместо ответа, если ваше сообщение не содержит решения. Кроме того, условием этой проблемы является то, что ширина элемента заранее неизвестна , поэтому процент не может быть использован для решения.