Показать/скрыть некоторый текст в большом тексте

Вопрос или проблема

Показать/скрыть некоторый текст в большом тексте

Я пытаюсь показать/скрыть некоторый текст (выделение) в середине абзаца. Эти критерии являются основными:

  1. Метод должен быть гибким, чтобы работать как в однострочном, так и в многострочном режиме.
  2. И я не хочу, чтобы он мешал остальному тексту абзаца line-height.

Ниже приведены то, что у меня есть на данный момент, но ни одно из них не совсем правильно. Версия 1 имеет переход, который я предпочитаю, т.е. ширина тега <mark> сокращается до нуля, и используется overflow: hidden, чтобы скрыть текст по мере уменьшения его размера. Проблема в том, что это не может быть многострочным. Версия 2 – это компромисс, который уменьшает font-size: 0px;, но может быть многострочным.

Есть ли решение, чтобы это работало (выглядело как версия 1, но функционировало как версия 2)? Или есть ли другое решение для этого? (Я также пробовал transform: scaleX(0);, и это не работает).

body
{
    font-size: 15px;
    line-height: 21px;
    font-family: 'Open Sans';
}

.section
{
    position: relative;
    margin: 0px 0px 50px 0px;
    width: 500px;
    height: 210px;
    background: #eeeeee;
    border: 1px solid #666666;
}

.paragraph
{
    position: relative;
    width: 100%;
    height: 100%;
    display: inline;
    vertical-align: middle;
}

.paragraph1
{
    background: #00ffff;
}

.paragraph2
{
    background: #00ffff;
}

/* версия 1 */
.mark1
{
    position: relative;
    top: 2px;
    width: 150px;
    height: 21px;
    transition: all 1.0s;
    vertical-align: bottom;
    display: inline-block;
    overflow: hidden;
    white-space: pre;
}

.mark1 span
{
    position: relative;
    top: -2px;
    height: 23px;
    display: inline-block;
    background: #cccccc;
}

.mark1.hidden
{
  width: 0px;
  transition: all 1.0s;
}

/* версия 2 */
.mark2
{
    position: relative;
    transition: all 1.0s;
    vertical-align: bottom;
    background: #00ff00;
}

.mark2 span
{
    position: relative;
    padding: 0px 0px 0px 0px;
    background: #cccccc;
}

.mark2.hidden
{
  font-size: 0px;
  transition: all 1.0s;
}
<!DOCTYPE html>
<html lang="">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>пример</title>
  <link href="https://fonts.googleapis.com/css?family=Open Sans" rel="stylesheet">
</head>

<body>

<button onclick="
const collection = document.getElementsByClassName('mark1');

for (let i = 0; i < collection.length; i++) {
collection[i].classList.toggle('hidden');
}
">переключить версию 1</button>

<div class="section">
<div class="paragraph paragraph1">
Lorem Ipsum is<mark class="mark1"> <span>просто тестовый текст</span></mark> в печати и наборе текста. <mark class="mark1"><span>Lorem Ipsum</span> </mark>является стандартным тестовым текстом этой отрасли с 1500-х годов, когда неизвестный печатник взял галерею шрифтов и перемешал их, чтобы сделать образец шрифта. Он выстоял не только пять столетий, но и переход в электронную типографию, оставаясь по сути неизменным. Он стал популярным в 1960-х годах с выпуском таблиц Letraset, содержащих отрывки Lorem Ipsum, а позже с программным обеспечением для настольной публикации, таким как Aldus PageMaker, включая версии Lorem Ipsum.
</div>
</div>

<button onclick="
const collection = document.getElementsByClassName('mark2');

for (let i = 0; i < collection.length; i++) {
collection[i].classList.toggle('hidden');
}

">переключить версию 2</button>

<div class="section">
<div class="paragraph paragraph2">
Lorem Ipsum is просто тестовый текст печати и набором. Lorem Ipsum был<mark class="mark2"> <span>стандартный тестовый текст этой отрасли с 1500-х годов</span></mark>, когда неизвестный печатник взял галерею шрифтов и перемешал их, чтобы сделать образец шрифта. Он выстоял не только пять столетий, но и переход в электронную типографию, оставаясь по сути неизменным. Он стал популярным в 1960-х с выходом листов Letraset, содержащих отрывки Lorem Ipsum, а более поздно с программным обеспечением для настольной публикации, таким как Aldus PageMaker, включая версии Lorem Ipsum.
</div>
</div>

</body>

</html>
</div><div class="s-prose js-post-body" itemprop="text">

Чтобы достичь этого, вам нужно как минимум 2 элемента

<mark class="mark1">
    <span class="mark-placeholder">просто тестовый текст</span>
    <span class="mark-highlight">просто тестовый текст</span>
</mark>

На этом этапе вы можете анимировать ширину у mark-placeholder и изменять mark-hightlight как угодно, не нарушая макет, так как он абсолютный.

body
{
    font-size: 15px;
    line-height: 21px;
    font-family: 'Open Sans';
}

.section
{
    position: relative;
    margin: 0px 0px 50px 0px;
    width: 500px;
    height: 210px;
    background: #eeeeee;
    border: 1px solid #666666;
}

.paragraph
{
    position: relative;
    width: 100%;
    height: 100%;
    display: inline;
    vertical-align: middle;
}

.paragraph1
{
    background: #00ffff;
}

.paragraph2
{
    background: #00ffff;
}

/* версия 1 */
.mark1
{
    position: relative;
    width: 150px;
    height: 21px;
    transition: all 1.0s;
    vertical-align: bottom;
    display: inline-block;
    overflow: hidden;
    white-space: pre;
}

.mark1.hidden
{
  width: 0px;
  transition: all 1.0s;
}

.mark-placeholder
{
position: relative;
opacity: 0;
display: inline-block;
}

.mark-hightlight
{
box-sizing: border-box;
display: block;
color: red;
background-color: #cccccc;
z-index: 1;
position: absolute;
bottom: 0%;
top: -0;
left: 0%;
right: 0%;
transform: translateY(-10%);
}
<!DOCTYPE html>
<html lang="">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>пример</title>
  <link href="https://fonts.googleapis.com/css?family=Open Sans" rel="stylesheet">
</head>

<body>

<button onclick="
const collection = document.getElementsByClassName('mark1');

for (let i = 0; i < collection.length; i++) {
collection[i].classList.toggle('hidden');
}
">переключить версию 1</button>

<div class="section">
<div class="paragraph paragraph1">
Lorem Ipsum is<mark class="mark1"> <span class="mark-placeholder">просто тестовый текст</span><span class="mark-hightlight">просто тестовый текст</span></mark> в печати и наборе текста. был стандартным тестовым текстом этой отрасли с 1500-х годов, когда неизвестный печатник взял галерею шрифтов и перемешал их, чтобы сделать образец шрифта. Он выстоял не только пять столетий, но и переход в электронную типографию, оставаясь по сути неизменным. Он стал популярным в 1960-х годах с выпуском листов Letraset, содержащих отрывки Lorem Ipsum, а более поздно с программным обеспечением для настольной публикации, таким как Aldus PageMaker, включая версии Lorem Ipsum.
</div>
</div>

<button onclick="
const collection = document.getElementsByClassName('mark2');

for (let i = 0; i < collection.length; i++) {
collection[i].classList.toggle('hidden');
}

">переключить версию 2</button>

<div class="section">
<div class="paragraph paragraph2">
Lorem Ipsum is просто тестовый текст печати и набором. Lorem Ipsum был<mark class="mark2"> <span>стандартный тестовый текст этой отрасли с 1500-х годов</span></mark>, когда неизвестный печатник взял галерею шрифтов и перемешал их, чтобы сделать образец шрифта. Он выстоял не только пять столетий, но и переход в электронную типографию, оставаясь по сути неизменным. Он стал популярным в 1960-х с выходом листов Letraset, содержащих отрывки Lorem Ipsum, а более поздно с программным обеспечением для настольной публикации, таким как Aldus PageMaker, включая версии Lorem Ipsum.
</div>
</div>

</body>

</html>

Ответ или решение

Для решения задачи отображения и скрытия текста в середине абзаца с учетом заданных условий (гибкость для однострочных и многострочных текстов, а также без изменения высоты строк в остальной части абзаца) можно использовать комбинацию CSS и JavaScript с двумя элементами внутри одного тега <mark>.

Решение

HTML-код:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Пример отображения/скрытия текста</title>
    <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
</head>
<body>

    <button onclick="
        const collection = document.getElementsByClassName('mark1');
        for (let i = 0; i < collection.length; i++) {
            collection[i].classList.toggle('hidden');
        }
    ">Переключить выделение</button>

    <div class="section">
        <div class="paragraph">
            Lorem Ipsum это&lt;mark class="mark1"&gt; 
            &lt;span class="mark-placeholder"&gt;стандартный текст&lt;/span&gt;
            &lt;span class="mark-highlight"&gt;стандартный текст&lt;/span&gt;
            &lt;/mark&gt; печатной и наборной промышленности.
        </div>
    </div>

</body>
</html>

CSS-код:

body {
    font-size: 15px;
    line-height: 21px;
    font-family: 'Open Sans', sans-serif;
}

.section {
    position: relative;
    margin: 0 0 50px;
    width: 500px;
    background: #eeeeee;
    border: 1px solid #666666;
}

.paragraph {
    position: relative;
    width: 100%;
}

.mark1 {
    position: relative;
    display: inline-block;
    overflow: hidden;
    transition: width 1s;
}

.mark1.hidden {
    width: 0;
}

.mark-placeholder {
    opacity: 0;
    display: inline-block;
}

.mark-highlight {
    display: block;
    background-color: #cccccc;
    position: absolute;
    inset: 0; /* Занимает всю площадь контейнера */
    color: red; /* Цвет текста выделения */
}

Объяснение работы

  1. Структура HTML: Мы используем тег <mark>, чтобы обернуть текст, который мы хотим скрывать или отображать. Внутри него находятся два <span> элемента: один (с классом mark-placeholder) служит для поддержания необходимости в пространстве, когда выделенный текст скрыт, а другой (с классом mark-highlight) — это текст, который должен отображаться и скрываться.

  2. Стили CSS:

    • .mark1 имеет свойства overflow: hidden и transition: width 1s, что позволяет анимировать изменение ширины, когда текст скрывается.
    • Класс .hidden сжимает ширину элемента <mark> до нуля, эффективно скрывая текст.
    • .mark-placeholder имеет opacity: 0, поэтому его фактически не видно, но он занимает пространство в документе, чтобы высота строки остального текста оставалась неизменной.
    • .mark-highlight позиционируется абсолютно, занимая все пространство, что обеспечивает корректное отображение текста выделения.
  3. JavaScript для переключения: Кнопка вызывает функцию, которая переключает класс .hidden у всех элементов с классом mark1, скрывая или отображая текст при нажатии.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...