Статьи

Реализация функциональности «Показать больше / меньше» с помощью чистого CSS

В настоящее время разработчики используют различные методы CSS для создания ползунков, модалов, всплывающих подсказок и многих других компонентов на основе Javascript.

В этой статье мы будем работать с некоторыми из этих методов, чтобы реализовать то, что мы можем назвать «Показать больше / меньше», и делать это без написания JavaScript. Мы также создадим полностью функциональную демонстрационную программу «показать / скрыть» в стиле аккордеона, которую вы сможете использовать в качестве отправной точки для своих проектов.

Нам есть что рассказать (техники, подводные камни и проблемы), так что давайте начнем!

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

Требования CSS

Чтобы лучше понять процесс создания этой функциональности, вы должны быть знакомы со следующими ключевыми понятиями CSS:

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

Просто нажмите на одну из кнопок, чтобы просмотреть описание и демонстрацию техники.

Разметка

Структура HTML для нашей демонстрации показана ниже:

 <ul> <li><a href="#">One</a></li> <li><a href="#">Two</a></li> <li><a href="#">Three</a></li> <li><a href="#">Four</a></li> <li class="container"> <input type="checkbox" id="check_id"> <label for="check_id"></label> <ul> <li><a href="#">Five</a></li> <li><a href="#">Six</a></li> <!-- more list items here --> </ul> </li> </ul> 

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

Определение основных стилей

После структурирования демонстрации мы определим несколько стилей сброса для наших элементов. Ничего особенного, просто несколько простых правил CSS, которые позволят нам улучшить внешний вид нашего компонента. Посмотрите на два набора правил ниже:

 ul { width: 50%; margin-left: auto; margin-right: auto; list-style-type: none; background: white; } li { height: 50px; line-height: 50px; border-top: 1px solid #e9ecef; } 

Стилизация контейнера флажка

В этой части руководства мы настроим стили для последнего элемента списка.

Сначала мы изменим значение вышеупомянутого свойства height . Затем мы устанавливаем его положение relative . Это значение свойства важно, потому что оно поможет нам позиционировать элемент label :

 .container { position: relative; height: auto; } 

Далее мы скрываем флажок:

 [type="checkbox"] { position: absolute; left: -9999px; } 

… и стилизовать соответствующий ярлык:

 label { background: #e4e3df; display: block; width: 100%; height: 50px; cursor: pointer; position: absolute; top: 0; } 

Обратите внимание, что мы позиционируем нашу метку абсолютно и назначаем ей верхнее смещение 0 пикселей. Так что теперь вам может быть интересно, нужны ли нам эти два свойства. На первый взгляд они кажутся ненужными. Но, как мы увидим через некоторое время, это обязательные декларации.

Если вы посмотрите на структуру HTML, вы увидите, что метка является пустым элементом. Мы сделали это предположение, потому что хотим, чтобы его содержимое менялось в зависимости от состояния флажка. Чтобы достичь этого, мы используем псевдоэлементы CSS. Если флажок не установлен (поведение по умолчанию), появляется ключевое слово More . Также для стилизации мы используем несколько символов, взятых из прекрасного веб-приложения CopyPasteCharacter .

Следующий фрагмент кода показывает, как мы стилизуем псевдоэлементы, связанные с элементом label :

 label:before, label:after { position: absolute; } label:before { content: 'More'; left: 10px; } label:after { content: '⇣●'; right: 10px; animation: sudo .85s linear infinite alternate; } @keyframes sudo { from { transform: translateY(-2px); } to { transform: translateY(2px); } } тем label:before, label:after { position: absolute; } label:before { content: 'More'; left: 10px; } label:after { content: '⇣●'; right: 10px; animation: sudo .85s linear infinite alternate; } @keyframes sudo { from { transform: translateY(-2px); } to { transform: translateY(2px); } } 

Last Последнее, что требуется, — это убедиться, что соседний элемент по умолчанию скрыт по умолчанию перед установкой флажка:

 [type="checkbox"] ~ ul { display: none; } 

onclick событие onclick

В этом случае, если мы активируем «проверенное» состояние флажка, запускается ряд правил CSS. Давайте исследуем их!

Первое из этих правил, которое позволяет нам выявлять скрытые элементы, показано ниже:

 [type="checkbox"]:checked ~ ul { display: block; } 

Далее мы меняем положение нашего лейбла. Цель состоит в том, чтобы разместить его в нижней части родительского элемента, прямо под неупорядоченным списком. Для этого мы используем top: 100%; , В качестве быстрого напоминания (даже если это выходит за рамки данной статьи) имейте в виду, что top: 100%; и bottom: 0; не дают тот же результат. В нашем случае мы используем первое:

 [type="checkbox"]:checked + label { top: 100%; } 

И последнее, но не менее важное: мы должны изменить содержание ярлыка. Как и в предыдущем разделе, мы генерируем желаемый контент, используя псевдоэлементы:

 [type="checkbox"]:checked + label:before { content: 'Less'; } [type="checkbox"]:checked + label:after { content: '⇡●'; } 

Выполнив все вышеперечисленные шаги, мы теперь сможем реализовать хороший эффект переключения с простым CSS.

Посмотрите демоверсию CodePen ниже:

Здесь нужно отметить одну вещь: расширяемый контент может быть практически любым. Я использую список, и компонент выглядит как традиционный виджет аккордеона. Но это не то, что это. Это компонент, половина содержимого которого скрыта и позволяет отображать / скрывать оставшуюся часть одним щелчком мыши.

Компонент выглядит красиво, но все еще есть возможности для улучшения! Точнее, если вы внимательно посмотрите на демонстрацию, вы заметите, что нет никаких установленных переходов между включенным и выключенным состояниями флажка. Это делает окончательный результат немного уродливым, не так ли? Так что давайте исправим эту проблему, работая над второй обновленной версией!

Добавление переходов

Новая версия направлена ​​на плавный переход между «проверенным» и «непроверенным» состояниями. Однако прежде чем показать, как мы можем это сделать, мы должны сначала понять, какие свойства CSS являются анимируемыми. К счастью, W3C сообщает нам полезную таблицу .

Давайте теперь вернемся к следующим правилам CSS:

 [type="checkbox"] ~ ul { display: none; } [type="checkbox"]:checked ~ ul { display: block; } 

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

 [type="checkbox"] ~ ul { overflow: hidden; height: 0; transition: all .45s cubic-bezier(.44,.99,.48,1); } [type="checkbox"]:checked ~ ul { height: 300px; /* this value will work */ height: auto; /* this value will not work */ } 

Еще раз, имейте в виду, что мы не можем перевести свойство height в значение auto . Это означает, что мы должны определить статическое значение (например, 300 пикселей). Таким образом, из-за этого ограничения свойство height не может рассматриваться как хорошее решение.

Лучше всего использовать свойство max-height . Однако этот параметр также имеет ограничения. В зависимости от реальной высоты содержимого, которое мы хотим показать, и значения свойства, которое мы установили, эффект перехода будет иметь различную скорость. В общем, свойство max-height может быть решением (фактически эффективным решением) только тогда, когда мы можем контролировать высоту соответствующего элемента. В противном случае, JavaScript будет единственным вариантом.

Обязательно ознакомьтесь с этим потоком StackOverflow о переходе свойства height .

Вот стили, которые мы заменяем по сравнению с предыдущими:

 [type="checkbox"] ~ ul { max-height: 0; } [type="checkbox"]:checked ~ ul { /** * the value below corresponds to the * height of the `ul` element * if we set a slightly larger value (eg 500px) * we won't see a great difference */ max-height: 300px; /** * try to replace the previous line with * the following one and see the difference: * max-height: 9999px; */ } 

Последний шаг — это переход нашего лейбла. Помните, что его top значение изменяется в зависимости от состояния. Хотя, как упоминалось в предыдущем разделе, его начальная top: 0; Значение свойства казалось бесполезным, оно фактически обеспечивает отличный способ передачи этого свойства. Тем не менее, мы обновляем соответствующее правило, чтобы включить свойство transition :

 label { position: absolute; top: 0; transition: top .45s cubic-bezier(.44,.99,.48,1); } [type="checkbox"]:checked + label { top: 100%; } 

Кроме того, обратите внимание, что оба перехода имеют одинаковые свойства (то есть функции синхронизации и длительность). Хотя это и не нужно, это помогает нам создать эффект плавного перехода.

Смотрите заключительную демонстрацию ниже:

Что нужно помнить

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

Если вы вызываете «проверенное» состояние (нажмите на ярлык, чтобы открыть его) и не перемещаете курсор, происходит следующее:

  • В Chrome, Safari, IE и Opera курсор прилипает, и элемент «Пятый» не выделяется сразу, если вы не переместите курсор.
  • На Firefox демо работает как положено.

Вы можете дополнительно проверить это, добавив следующий CSS:

 label:hover { background: yellow; } 

Добавив это, вы увидите, что когда вы переключаете метку и не перемещаете позицию курсора, метка также остается в своем состоянии при наведении.

Пожалуйста, имейте в виду, что проблема выше происходит в основном во втором демо, где мы добавили переходы.

При этом, я не думаю, что это имеет большое значение, но я хотел поделиться этим с вами!

Вывод

В этой статье мы использовали технику «checkbox hack» вместе с селекторами одного уровня, чтобы реализовать функциональность «Show More / Less» с простым CSS. Создав две разные версии нашей демонстрации, мы получили хорошее представление о том, как далеко мы можем расширить пределы CSS.

Надеюсь, вам понравилась статья, и, возможно, она мотивирует вас создать что-то интересное только с помощью CSS.