Как стать автором
Поиск
Написать публикацию
Обновить

Сортировка списков на CSS

Время на прочтение3 мин
Количество просмотров21K
image

Знаю, звучит толсто. Но это правда возможно. Почти. Предлагаемый мной способ вряд ли применим в крупных проектах, но в мелких, для себя, типа «сайтов про кота», вполне рабочее решение. Возможность сортировки нам предоставит flexbox и css-переменные (они же custom properties) и js тут не потребуется.

Для начала создадим простой список критериев сортировки, который можно видеть почти в каждом интернет-магазине – по умолчанию, по цене (возрастание/убывание), по алфавиту (возрастание/убывание):

<input id="q1" type="radio" name="sort" checked>
<label for="q1">По умолчанию</label><br>

<input id="q2" type="radio" name="sort">
<label for="q2">По цене, по возрастанию</label><br>

<input id="q3" type="radio" name="sort">
<label for="q3">По цене, по убыванию</label><br>

<input id="q4" type="radio" name="sort">
<label for="q4">По алфавиту, по возрастанию</label><br>

<input id="q5" type="radio" name="sort">
<label for="q5">По алфавиту, по убыванию</label><br>

А так же сам сортируемый список. В этом списке каждый элемент имеет название товара (в данном случае «Первый», «Второй» и т.п. и цену товара).

<div class="wrapper">
	   <div class="item">Первый - 20000</div>
	   <div class="item">Второй - 17550</div>
	   <div class="item">Третий - 17549</div>
	   <div class="item">Четвертый - 17549</div>
	   <div class="item">Пятый  - 17549</div>
</div>

.wrapper {
	display: flex;
	flex-direction: column;
}

Что означает отсортировать список? Это значит, нам нужно поменять взаимное расположение элементов в списке. Потомкам flex-блока можно задать свойство order для изменения порядка их следования в блоке. Если order не задан для элемента, его значение равно нулю. Элемент с большим значением order будет поставлен ближе к концу блока, элемент с меньшим – ближе к началу. Таким образом, нам нужно всего лишь добавить некие сведения о порядке расположения элементов списка в свойство order каждого элемента. В этом нам помогут css-переменные (inline-css тут для наглядности).

<div class="wrapper">
	   <div class="item" style="--default: 1; --cost: 20000; --title: 2;">
	   	   Первый - 20000
           </div>
	   <div class="item" style="--default: 2; --cost: 17550; --title: 1;">
	   	   Второй - 17550
           </div>
	   <div class="item" style="--default: 3; --cost: 17549; --title: 4;">
	   	   Третий - 17549
	   </div>
	   <div class="item" style="--default: 4; --cost: 17549; --title: 5;">
	   	   Четвертый - 17549
	   </div>
	   <div class="item" style="--default: 5; --cost: 17549; --title: 3;">
	   	   Пятый  - 17549
	   </div>
</div>

И подставив в order значение из css-переменной мы получим элементы расставленные в нужном порядке.

/* по умолчанию */
#q1:checked ~ .wrapper > .item {
	order: var(--default);
}
/* по цене */
#q2:checked ~ .wrapper > .item,
#q3:checked ~ .wrapper > .item {
	order: var(--cost);
}
/* по алфавиту */
#q4:checked ~ .wrapper > .item,
#q5:checked ~ .wrapper > .item {
	order: var(--title);
}

Для сортировки по возрастанию/убыванию можно использовать свойство flex-direction:

#q3:checked ~ .wrapper,
#q5:checked ~ .wrapper {
	flex-direction: column-reverse;
}

К сожалению, сразу становится очевидна проблема «почти», о которой я упомянул в начале – порядок следования элементов, заданный в css-переменных должен быть определен заранее. И если с ценой это не представляет особой проблемы, можно просто указать значение в переменной --cost как есть, то с остальными сортировками, по умолчанию и по алфавиту, придется заранее раздать элементам индексы. К плюсам решения можно отнести то, что изменения в порядке сортировки применяются мгновенно.

→ Вот рабочий прототип
Теги:
Хабы:
Всего голосов 19: ↑15 и ↓4+11
Комментарии5

Публикации

Ближайшие события