Расположите элементы в столбцах, смещенных по вертикали относительно друг друга - PullRequest
0 голосов
/ 16 декабря 2018

Я ищу способ достижения этого эффекта:

На мобильном макете элементы размещаются один под другим в столбце:

enter image description here

Однако на макете рабочего стола элементы размещаются в двух столбцах, с нечетными элементами в одном столбце и четными элементами в другом.Столбцы смещены по вертикали относительно друг друга:

enter image description here

Интересно, существует ли способ позиционирования только для CSS.Сетка CSS очень заманчиво приближается, если бы только был способ сказать, что, например, nth-child(n+1) будет охватывать строки 1 и 2, а `nth-child (2n) будет охватывать строки 2 и 3, и так далее, но яя не уверен, может ли CSS сетка сделать это.Возможно, вы знаете, как это сделать?

ОБНОВЛЕНО: Я полагаю, это очень грубое приближение CSS того, что я имею в виду, используя встроенные блоки: https://codepen.io/anon/pen/JwXVox. Я бы приветствовал лучшую технику.

Ответы [ 3 ]

0 голосов
/ 16 декабря 2018

Вы можете сделать это с помощью селекторов Flexbox , calc() , :nth-child() , :not() псевдокласс и, конечно, @media запросов :

.flex {
  display: flex; /* displays flex-items (children) inline */
  flex-wrap: wrap; /* enables their wrapping */
}

.flex > div {
  flex-basis: calc(50% - 10px); /* initial width set to 50% of the parent's - left & right margins */
  height: 100px;
  margin: 0 5px; /* preferably top & bottom margins set to zero to keep calculations simple */
  border: 1px solid;
  box-sizing: border-box; /* because of the borders, also recommended in general */
}

.flex > div:nth-child(2){
  margin-top: 55px; /* half of divs height + half of the desired gap between them; modification affects all but the first div */
}

.flex > div:nth-child(odd):not(:first-child){
  margin-top: -45px; /* - half of divs height + half of the desired gap between them, so in this case the gap is 10px (2 x 5px); modification affects all but the first odd div (if ofc. modification is "")  */
}

.flex > div:nth-child(even):not(:nth-child(2)){
  margin-top: 10px; /* gap size; modification affects all but the first three divs */
}

@media (max-width: 600px){
  .flex {flex-direction: column} /* stacks flex-items vertically */
  .flex > div {flex-basis: auto} /* initial width set to default or 100% */
  .flex > div:not(:first-child) {margin-top: 10px !important}
}
<div class="flex">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
</div>
0 голосов
/ 17 декабря 2018

A float подход

.container {
  width: 250px;
  margin: 0 auto;
}

.item {
  width: 100px;
  height: 100px;
  border: 1px solid black;
  margin-top: calc(100px/3);
}

.item:first-child {
  margin-top: 0;
}


@media (min-width: 400px) {
  .item:nth-child(even) {
    float: right;
    margin-top: calc(-100px/3);
  }
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
0 голосов
/ 16 декабря 2018

Предположительно, вы знаете, как создать мобильную версию и как использовать @media для различения экранов разных размеров.

Я не до конца понял, что вы имели в виду ", охватывают строки 1 и 2", но вам не нужно использовать сетку.Хорошие старомодные встроенные блоки прекрасно работают здесь.Ваше грубое приближение является грубым только потому, что ваши значения маржи приблизительно оценены, а не потому, что техника, которую вы используете, недостаточна, чтобы делать то, что вы хотите.

Вот что я сделал, чтобы расположить элементы .grid-element (и это выглядит довольно даже для меня; возможно, это достаточно близко к тому, что вы хотите для его точной настройки):

  1. Все элементы: верхнее поле 0, левое / правое поля 1%, нижнее поле 10 пикселей.
  2. Второй элемент (первый элемент в правом столбце): верхнее поле 50 пикселей.
  3. Все нечетные элементы, кроме первого: верхнее поле -50px.

Вы можете поэкспериментировать с различными значениями поля, чтобы увидеть эффект, который они оказывают.Но, по сути, как только вы установите их рядом, вы столкнете вторую.Это правильно позиционирует второй и первый элементы, но также удаляются все последующие элементы.Итак, мы хотим восстановить четные с отрицательным значением маржи.Однако мы не хотим поднимать первый, так как он никогда не сталкивался.Итак, мы исключаем его с помощью селектора nth-child(2n+3) (т.е. каждый второй элемент начинается с трех).Это эквивалентно использованию nth-child(odd):not(:first-child).

function fillGrid() {
  const container = document.querySelector('.container');
  const times = [...new Array(10)];
  times.forEach(() => {
    const element = document.createElement('div');
    element.classList.add('grid-element');
    container.appendChild(element);
  });
}

fillGrid()
.container {
  width: 60%;
  margin: auto;
  background: papayawhip;
  padding-bottom: 60px;
}

.grid-element {
  display: inline-block;
  height: 50px;
  background: green;
  vertical-align: middle;
  width: 48%;
  margin: 0 1% 10px;
}

.grid-element:nth-child(2) {
  margin-top: 60px;
}

.grid-element:nth-child(2n+3) {
  margin-top: -60px;
}
<div class="container">
</div>

РЕДАКТИРОВАТЬ: Использование сетки CSS для получения того же результата

После нашего разговора в комментарияхЯ экспериментировал с position:grid, чтобы посмотреть, смогу ли я найти способ сделать это.Мне пришлось добавить строку javascript (или написать довольно громоздкую связку CSS), чтобы сделать это, но, похоже, это сработало.

Я просто установил высоту строки на 25%, а затем добавил строку в свой JavaScript, чтобы сделать каждую строку толщиной в две строки, и начал ее на одну строку ниже от предыдущего элемента.

function fillGrid() {
  const container = document.querySelector('.container');
  const times = [...new Array(10)];
  times.forEach((e, index) => {
    const element = document.createElement('div');
    element.classList.add('grid-element');
    //added the line below to size and position the elements
    element.setAttribute("style", "grid-row-start: " + (index + 1) + "; grid-row-end: " + (index + 3) + ";");
    element.textContent = index + 1; //also put a number in each box
    container.appendChild(element);
  });
}

fillGrid()
.container {
  display: grid;
  grid-gap: 5px;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 25px;
  width: 60%;
  margin: auto;
  background: papayawhip;
}

.grid-element {
  background: green;
  color: white;
}
<div class="container">
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...