#html #css
#HTML #css
Вопрос:
Есть ли какой-либо способ добиться макета, показанного в этом макете?
Дополнительный текст выравнивается по правому краю, и если есть пробел, он разделяет тот же линейный блок, что и последняя строка основного текста.
Вещи, которые я пробовал
Плавающий дополнительный текст.
Проблемы с этим подходом:
- Это float, поэтому у него есть все крайние случаи и ошибки, которые есть у поплавков, и следующий элемент должен иметь дело с его очисткой, а поля действуют неожиданным образом.
- Если дополнительный текст имеет другой размер, его трудно выровнять по той же базовой линии, что и основной текст, поскольку
vertical-align
он не работает с плавающими элементами. Их можно выровнять, если известны все размеры, но в большинстве случаев для этого потребуются дополнительные элементы-оболочки. - Чтобы использовать ту же строку, что и основной текст, дополнительный текст должен быть первым (для меня это неприемлемо) или основной текст должен быть плавающим, а не дополнительным. И последний случай работает только тогда, когда основной текст и дополнительный текст умещаются на одной строке, в противном случае дополнительный будет находиться ниже конечного линейного блока основного текста.
Вот он с дополнительным текстом, расположенным справа, в обоих порядках:
article {
clear: both;
}
header p {
float: right;
}
<article>
<header>
<h2>Lorem ipsum dolor sit amet, adipiscing</h2>
<p>Supplementary</p>
</header>
</article>
<article>
<header>
<p>Supplementary</p>
<h2>Lorem ipsum dolor sit amet, adipiscing</h2>
</header>
</article>
Flexbox
Это лучше в одном смысле: гибкие элементы могут быть выровнены по базовой линии без дополнительных оберток и сложного стиля. Однако:
- Если функция flex wrap не включена, дополнительный текст будет выравниваться только по первой базовой линии основного текста, а горизонтальная область, доступная для всех строк основного текста, уменьшается на то, сколько места занимает дополнительный текст.
- Если включена функция flex wrap и основной текст переносится на вторую строку или иным образом не оставляет достаточно места для дополнительного текста, ширина элемента flex основного текста равна полной ширине гибкого блока или близка к ней, и поэтому дополнительный текст всегда будет находиться на новой гибкой строке, даже если для него доступно визуальное пространство в последнем линейном блоке основного текста.
header {
display: flex;
align-items: baseline;
}
header p {
margin-left: auto;
}
<header>
<h2>Lorem ipsum dolor sit amet, adipiscing</h2>
<p>Supplementary</p>
</header>
<header style="flex-wrap: wrap">
<h2>Lorem ipsum dolor sit amet, adipiscing</h2>
<p>Supplementary</p>
</header>
Абсолютное позиционирование
Это бесполезно, поскольку при абсолютном расположении дополнительный текст не резервирует места и может перекрываться с основным текстом.
Комментарии:
1. чтобы легко очистить float, просто добавьте
overflow:auto
в заголовок, это сделает элемент самоочищающимся, и не нужно беспокоиться о следующем элементе, очищающем его
Ответ №1:
Это, безусловно, интересный вопрос. К сожалению, на самом деле это кажется основным inline
floated
способом использования элементов и, какими бы неприятными они ни были. Конечно, немного сложнее понять, как они будут взаимодействовать в среде «реального мира», но если бы вы использовали исправление « :after
как таблица», сделали h2
его встроенным, плавающим p
и удалили высоту строки, он должен находиться в нижней части типографский x-высота h2
.
Вот краткая демонстрация:
article:after {
content: "";
display: table;
clear: both;
}
header h2 {
display: inline;
}
header p {
float: right;
line-height: 0;
}
/* Just for example layout */
body{width:100vw;overflow-x:hidden;min-height:100vh;display:flex;align-items:center;justify-content:center}div{max-width:50%}header p{position:relative}header p:after{content:"";position:absolute;width:calc(50vw - 40px);height:1px;background:red;top:6px;right:0}article{padding:20px;border:1px solid #ccc}
<div>
<article>
<header>
<h2>Lorem ipsum</h2>
<p>Supplementary</p>
</header>
</article>
<article>
<header>
<h2>Lorem ipsum dolor sit amet, adipi…</h2>
<p>Supplementary</p>
</header>
</article>
<article>
<header>
<h2>Lorem ipsum dolor sit amet, adipiscing Lorem ipsum dolor sit amet, adipiscing Lorem ipsum dolor sit amet, adipiscing Lorem ipsum.</h2>
<p>Supplementary</p>
</header>
</article>
</div>
Интересное замечание, как отметил @Temani Afif, вы можете заменить на article:after { content: ""; display: table; clear: both; }
с header { overflow: auto; }
, чтобы сделать его самоочищающимся. Небольшая хитрость, позволяющая предотвратить засорение вашего CSS четкими исправлениями
Комментарии:
1. О, это показывает, что в
display: contents
ответе used in nullqube не было необходимости; это улучшение. Расширенный пример здесь: codepen.io/tremby/pen/mdrXQYO — как вы увидите, я проделал много акробатических трюков, чтобы убедиться, что различия в высоте и размере линий учитываются во всех случаях…2. Расширенный пример в моем предыдущем комментарии также обрабатывает несколько дополнительных строк (вместо установки высоты строки в 0, как в вашем примере). Я думаю, это решает проблему почти полностью, просто жаль, что размеры шрифта должны быть известны, что для выравнивания базовых линий требуется так много неприятностей
calc
, что задействовано магическое число, и что если дополнительный элемент один в строке, он занимает всю высоту строкиосновной текст.3. Очистка etc — широко известная проблема, и ее не нужно указывать в ответе. Ничего, если я отредактирую ваш ответ, включив в него свой расширенный пример?
4. Я также должен отметить, что в вашем (гораздо более чистом и простом!) коде базовые линии выравниваются только по счастливой случайности — если размер шрифта основного или дополнительного текста изменен, они больше не будут выравниваться.
Ответ №2:
h2 {
display: contents;
}
p {
float: right;
transform: translateY(-50%);
}
article {
clear: both;
}
article:after {
content: "";
display:block;
width: 100%;
height: 1px;
background: red;
}
<article>
<header>
<h2>Lorem ipsum dolor sit amet, adipiscing blah blahh blahhhh, and long looong looooooong text content</h2>
<p>Supplementary</p>
</header>
</article>
<br>
<article>
<header>
<p>Supplementary</p>
<h2>Lorem ipsum dolor sit amet, adipiscing</h2>
</header>
</article>
а затем без display: contents
и появившийся дополнительный пробел можно решить, установив line-height
значение h2 (например: line-height:1em;
)
h2 {
display: inline;
/*line-height: 1em;*/
}
p {
float: right;
transform: translateY(-50%);
}
article {
clear: both;
}
article:after {
content: "";
display:block;
width: 100%;
height: 1px;
background: red;
}
<article>
<header>
<h2>Lorem ipsum dolor sit amet, adipiscing blah blahh blahhhh, and long looong looooooong text content</h2>
<p>Supplementary</p>
</header>
</article>
<br>
<article>
<header>
<p>Supplementary</p>
<h2>Lorem ipsum dolor sit amet, adipiscing</h2>
</header>
</article>
Комментарии:
1. Интересно. Я взял это и запустил с ним; смотрите здесь: codepen.io/tremby/pen/NWRyEMv — основная проблема заключается в том, что
display: contents
это поддерживается не везде, и в браузерах на основе Chromium есть текущая ошибка, из-за которой она удаляется из дерева доступности (ссылка в примечаниях Codepen).2. ооо, вы можете получить тот же результат и с
display:inline;
помощью too @tremby