Чтобы лучше понять это, давайте сначала добавим пропущенные случаи.
.flexy {
display: inline-flex;
}
.noname::before {
content: ' has ';
}
.noname-after::after {
content: ' has ';
}
span {
border:1px solid;
}
<div class="flexy">
A girl <span class="noname">no name</span>
</div>
<br>
<div class="flexy">
A girl <span class="noname"><span>no name</span></span>
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"><span>no name</span></span> some text after
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"></span><span>no name</span> some text after
</div>
<br>
<div class="flexy">
Jon Snow
<span> knows </span>
<span>nothing</span>
</div>
Мы ясно видим, что при использовании before
мы пропускаем начальный пробел, а при использовании after
и завершающий - и то и другое, если только after
(или before
) находится внутри диапазона.
Другими словами, мы пропускаем пробелы по краям всех элементов <span>
(с использованием или без использования псевдоэлемента), и это логично, поскольку это стандартное поведение white-space
. Из спецификации :
Как выложена каждая строка,
- Если для пробела (U + 0020) в начале строки для 'пробела' установлено значение 'normal', 'nowrap' или 'pre-line', it удаляется .
- Все вкладки (U + 0009) отображаются в виде горизонтального сдвига, который выравнивает начальный край следующего глифа с помощью следующей остановки табуляции. Остановка табуляции происходит в точках, кратных 8-кратной ширине пробела (U + 0020), отображаемого в шрифте блока от начального края содержимого блока.
- Если для пробела (U + 0020) в конце строки для «пробела» установлено значение «normal», «nowrap» или «pre-line», it также удаляется .
- Если для пробелов (U + 0020) или табуляций (U + 0009) в конце строки для «пробела» установлено значение «pre-wrap», UA могут визуально свернуть их.
Теперь вы скажете мне, что мы имеем дело с span
элементами, и у нас нет блоков и новых строк, но мы находимся внутри гибкого контейнера, таким образом, каждый элемент будет заблокирован, и здесь действуют вышеуказанные правила.
Отображаемое значение гибкого элемента блокируется ref
Стоит отметить, что псевдоэлемент не является прямым потомком гибкого контейнера, поэтому он остается встроенным элементом внутри блочного элемента. Если мы изменим их на блочный элемент (например, используя inline-block
1 ) ) вы увидите, что пробелы всегда исчезнут:
.flexy {
display: inline-flex;
}
.noname::before {
content: ' has ';
display:inline-block;
}
.noname-after::after {
content: ' has ';
display:inline-block;
}
span {
border:1px solid;
}
<div class="flexy">
A girl <span class="noname">no name</span>
</div>
<br>
<div class="flexy">
A girl <span class="noname"><span style="display:inline-block;">no name</span></span>
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"><span>no name</span></span> some text after
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"></span><span>no name</span> some text after
</div>
<br>
<div class="flexy">
Jon Snow
<span> knows </span>
<span>nothing</span>
</div>
Еще одна важная вещь, которую стоит отметить, это то, как flexbox обрабатывает пробелы:
Каждый дочерний поток в гибком контейнере становится гибким элементом, , и каждая непрерывная последовательность дочерних текстовых прогонов переносится в гибкий элемент анонимного контейнера контейнера . Однако , если вся последовательность дочерних текстовых прогонов содержит только пробел (т. Е. Символы, на которые может влиять свойство пробела), вместо этого не отображается (как если бы его текстовые узлы были отображены: нет).
Теперь мы можем ясно понять, что происходит. Внутри нашего flex-контейнера мы сначала создаем flex-элементы, удаляя все лишние пробелы между ними. Затем каждый элемент flex становится элементом уровня блока, и внутри мы применяем алгоритм пробелов, который удаляет завершающие и начальные пробелы внутри этого блока.
Вы можете изменить свойство white-space
, если хотите сохранить конечные и ведущие пробелы:
.flexy {
display: inline-flex;
}
.noname::before {
content: ' has ';
}
.noname-after::after {
content: ' has ';
}
span {
border:1px solid;
white-space:pre;
}
<div class="flexy">
A girl <span class="noname">no name</span>
</div>
<br>
<div class="flexy">
A girl <span class="noname"><span>no name</span></span>
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"><span>no name</span></span> some text after
</div>
<br>
<div class="flexy">
A girl <span class="noname-after"></span><span>no name</span> some text after
</div>
<br>
<div class="flexy">
Jon Snow
<span> knows </span>
<span>nothing</span>
</div>
Вот еще один пример, чтобы лучше понять, что происходит шаг за шагом:
span {
border:1px solid;
}
div {
border:1px solid red;
margin:10px 0;
}
Spaces are removed from the start and the end, spaces inside are kept (contiguous spaces are collapsed to only one space)
<div>
<span> text inside span </span> text without span<span> text inside span </span>
</div>
I made the last span inline-block so its first space inside is removed
<div>
<span> text inside span </span> text without span<span style="display:inline-block"> text inside span </span>
</div>
Spaces between flex items are removed (We have 3 items and one inside an anonymous block) then first and last space inside each flex items are also removed
<div style="display:flex;">
<span> text inside span </span> text without span<span> text inside span </span>
</div>
We change the white space algorithm and now all the spaces are kept
<div style="display:flex;white-space:pre;">
<span> text inside span </span> text without span<span> text inside span </span>
</div>
1: Это значение заставляет элемент генерировать контейнер блока встроенного уровня . Внутренняя часть встроенного блока отформатирована как блок box, а сам элемент отформатирован как атомный блок inline-level.