Розширювана текстова секція в HTML лише за допомогою CSS

Цей короткий пост є сильною адаптацією публікації на codingartistweb.com з незначними змінами, а фінальний код можна знайти в цьому JSFiddle.

Проблема

Під час налаштування інтерфейсу користувача для додатка, заснованого на вже існуючому проекті Django, я натрапив на проблему, коли деякі текстові значення у списку dl були занадто довгими (понад 1000 символів), і наявність деякої кількості таких елементів на одній сторінці змушувала користувача прокручувати сторінку, щоб дістатися до інших значень, особливо коли на сторінці були фіксовані бокові панелі, заголовки та футери.

Я бачив ці кнопки "Читати більше/менше" на багатьох сайтах, але не знав, як це працює насправді.

pic

Розгортаючийся текстовий блок

Також мені було важливо зробити це якнайпростіше, оскільки команда не дуже захоплюється UI.
На щастя, мені не потрібно підтримувати старі/застарілі веб-браузери.

Існуюче рішення

Шукаючи різні рішення (дякую stackoverflow спільноті), я натрапив на цей чудовий пост на codingartistweb.com, який точно відповідає моїм вимогам, із текстовим та відеоуроком. Код складається лише з HTML і CSS, без використання JavaScript. Він використовує невидимий checkbox, і код легко зрозуміти.
Що ще можна бажати?

Єдине, що мене турбує — це використання синтаксису `` як показано нижче.



Це чудово працює, якщо у вас є лише один розгортаємий текстовий блок, але не спрацює, якщо таких блоків кілька. Тоді рішенням буде генерувати (псевдо)випадкові ID або на стороні клієнта (JS), або на сервері (Python).

Покращення

Документація до елемента label показує два способи прив'язати мітку до елемента. Найпоширеніший спосіб — це використання атрибута for з ID цільового елемента. Інший спосіб — це вкладення цільового елемента всередину елемента label.


 Check  


Це функціонально (але не структурно) те ж саме, при цьому уникається використання унікальних ID, тому це можна легко повторити.
Це вимагає налаштування CSS для досягнення бажаного ефекту.

Остаточне рішення

Остаточне рішення полягає в наступних кроках:

  1. Розділити текст на 2 частини.
  2. Додати невидимі елементи після кожної частини тексту.
  3. Повторити пункти 1 і 2 кілька разів.
  4. Використати CSS для відображення/приховування відповідних частин.

Ось як виглядатиме HTML:



 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id massa consequat lectus semper dignissim quis eget erat. Maecenas rutrum leo vel ligula bibendum dictum.  
  Praesent ut facilisis neque, in aliquet felis. Nunc vitae facilisis nunc. Phasellus in elit eu quam ultricies mattis. Aenean eu arcu non nulla maximus dapibus. Proin eu massa ut mauris efficitur iaculis at sed dui. Aliquam at consectetur est. Nam eget dapibus nulla. Aliquam ornare fringilla porta.
Vestibulum sit amet rutrum magna, quis fringilla urna.  





 ```  Ось CSS, завдяки якому цей підхід працює, дякуючи [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference) [селекторам](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors), [комбінаторам](https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator), [псевдокласам](https://developer.mozilla.org/en-US/docs/Web/CSS/:checked) і [елементам](https://developer.mozilla.org/en-US/docs/Web/CSS/::before).  ``` .expand-text-p2 {    display: none;   }      .expand-text-dots:before {    content: "...";   }      .expand-text-check-label {    cursor: pointer;    background: orange   }      .expand-text-check-label:before {    content: "[+]";    position: relative;    font-family: monospace;   }      .expand-text-check-label:has(> .expand-text-check:checked):before {    content: "[-]";   }      .expand-text-dots:has(~ .expand-text-check-label > .expand-text-check:checked) {    display: none;   }      .expand-text-p2:has(~ .expand-text-check-label > .expand-text-check:checked) {    display: inline;   } ```  Цей підхід має наступні переваги.  1.
Не потрібно управляти ідентифікаторами HTML-елементів.
2. Дозволяє мати кілька розширюваних текстових секцій без змін у CSS.
3.
Не залишає візуальних артефактів, якщо CSS відсутній.

## Бонус

Під час цього я створив [фільтр шаблонів Django](https://docs.djangoproject.com/en/5.1/ref/templates/language/#filters), який виглядає наступним чином.

from django import template
from django.template.defaultfilters import stringfilter
from django.utils.html import conditionescape
from django.utils.safestring import mark
safe

register = template.Library()

@register.filter(needsautoscape=True)
@stringfilter
def expand
text(value: str, length: int = 200, autoescape: bool = True) -> str:

escape = conditional_escape if autoescape else lambda x: x

if len(value) > length:
part1 = escape(value[:length])
part2 = escape(value[length:])

spans = f'{part1}{part2}'
html = f'
{spans}'
else:
html = escape(value)

return mark_safe(html)
```

Це дозволяє створювати розширювані текстові секції з кастомною довжиною, як показано нижче.

{{ value | expand_text:100 }}

І все.
Сподіваюся, це допоможе.

Перекладено з: Expandable HTML text section with only CSS

Leave a Reply

Your email address will not be published. Required fields are marked *