Меньше абсолютного позиционирования с современным CSS

Меньше абсолютного позиционирования с современным CSS

От автора: каждый раз, когда я работаю над компонентом, которому требуется абсолютное позиционирование, я спрашиваю себя: действительно ли это необходимо? Я заметил несколько вариантов использования, в которых нет необходимости в position:absolute. Мне показалось это интересным, и захотел, задокументировать варианты использования, с которыми я обычно сталкивался, работая над проектами.

В этой статье я рассмотрю несколько вариантов использования, в которых абсолютное позиционирование не требуется.

Вступление

Если мы вернемся на 5 лет назад, CSS flexbox был все еще новым и не мог использовать надлежащих отступов. CSS-grid тогда даже не поддерживалась. В конце концов, мы использовали позиционирование CSS для достижения желаемого макета. Однако в наши дни некоторые из этих вариантов использования можно решить с помощью CSS flexbox или grid.
На днях мы работали над фронтендом целевой страницы, и мой партнер спросил меня о проблеме с макетом, с которой он столкнулся. Проблема возникла из-за position:absolute, я попытался помочь, и мы исправили эту проблему, даже не используя позиционирование CSS.

Случаи использования с примерами

Наложение в карточке

Когда у нас есть карточка, содержащая текст поверх изображения, мы часто используем position:absolute для размещения содержимого поверх изображения. В CSS-сетке это больше не требуется.

Меньше абсолютного позиционирования с современным CSS

Это типичная карточка с текстом поверх изображения. Вот HTML:

Чтобы разместить контент поверх изображения, нам нужно позиционировать .card__content абсолютно.

В приведенном выше примере нет ничего плохого, но почему бы не использовать более простое решение? Давайте исследуем это.

Первым делом нужно добавить display:grid в компонент карты. Нам не нужно устанавливать какие-либо столбцы или строки.

Меньше абсолютного позиционирования с современным CSS

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

Более того, мы можем использовать сокращение grid-area:

Меньше абсолютного позиционирования с современным CSS

Наконец, мы также можем использовать grid-area: 1/-1. -1 представляет собой последний столбец и строку в сетке.

Card Tag

Основываясь на предыдущем примере, мы хотим расширить его и включить тег в левую верхнюю часть карты. Для этого нам нужно использовать ту же технику grid-area: 1/-1, но мы не хотим, чтобы тег заполнял всю карту, верно?

Меньше абсолютного позиционирования с современным CSS

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

Познакомьтесь с тегом, который расположен над его родительским элементом, без использования position:absolute. Демо.

Herо-раздел

Еще один идеальный вариант использования — это hero-раздел с содержимым, перекрывающим изображение.

Меньше абсолютного позиционирования с современным CSS

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

Меньше абсолютного позиционирования с современным CSS

Есть разные способы реализовать это. Если изображение носит чисто декоративный характер, можно использовать background-image. В противном случае мы можем использовать элемент img.

Вот как мы можем реализовать hero-раздел, используя абсолютное позиционирование. Однако мы можем добиться большего. Давайте исследуем современный подход.

Во-первых, нам нужно добавить display:grid к hero-элементу. После этого мы применим ту же концепцию, что и в компоненте карты grid-area:1/-1, к каждому прямому дочернему элементу.

Меньше абсолютного позиционирования с современным CSS

К сожалению, нам нужно будет использовать фиксированную высоту для hero-секции, чтобы сработало правило .hero__thumb. (Дочерний элемент с height:100% требует, чтобы его родительский элемент имел явную фиксацию height, а не min-height).

Я хочу пройтись по пронумерованным строкам кода, поскольку они важны:

Мы можем использовать z-index сетки или flex элемента. Вообще не нужно добавлять position:relative.

Поскольку .hero__content это элемент сетки, использование margin:auto будет центрировать его по горизонтали и вертикали.

Не забывайте включать object-fit:cover при работе с изображениями.

Я использовал для hero-изображения min-height:0 в том случае, если использовалось большое изображение. Это сделано для того, чтобы заставить CSS-сетку учитывать height:100% и избегать увеличения размера изображения, больше чем hero-раздел, в случае, если автор использовал огромное изображение. Подробнее об этом вы можете прочитать в моей статье о минимальном размере содержимого в CSS-сетке.

Обратите внимание, как мы пришли к гораздо более чистому решению. Демо.

CSS display:contents

Я думаю, что это первый практический пример использования display:contents, который был для меня действительно полезный. Рассмотрим следующий пример, где у нас есть контент и изображение.

Меньше абсолютного позиционирования с современным CSS

До сих пор ничего странного. На мобильных устройствах мы хотим добиться следующего макета.

Меньше абсолютного позиционирования с современным CSS

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

На мобильном телефоне все может работать как положено. На десктопе нам нужно расположить img с правой стороны. И хотя это работает, но есть более простое решение display:contents. Вернемся к исходной разметке.

Обратите внимание, что содержимое завернуто внутрь .hero__content. Как мы можем сказать браузеру, что мы хотим, чтобы <h2>, <p> и <a> были наследниками того же родительского элемента, что и img? Что ж, с display:contents я могу это сделать:

Браузер проанализирует разметку следующим образом.

Все, что нам нужно сделать в CSS, это следующее.

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

Демо

Изменение порядка элементов компонентов карты

Меньше абсолютного позиционирования с современным CSS

В этом примере у нас есть вариант карты, в которой заголовок помещается вверху карты. Давайте посмотрим на разметку HTML.

Обратите внимание, что у нас есть два прямых дочерних элемента: ползунок и содержимое. Как с такой разметкой мы можем расположить заголовок h3 вверху? Мы можем сделать это с помощью абсолютного позиционирования.

Однако это решение может не сработать, если заголовок слишком длинный.

Меньше абсолютного позиционирования с современным CSS

Это происходит потому, что заголовок выходит за рамки обычного потока, поэтому браузер фактически не заботится о том, насколько он короткий или длинный. Мы можем найти гораздо лучшее решение используя display:contents:

Это позволит нам контролировать все дочерние элементы и иметь возможность записывать их по мере необходимости с помощью свойства order.

Меньше абсолютного позиционирования с современным CSS

У нас все еще есть небольшая проблема, так как мы добавили padding:1 rem родительскому элементу. Изображение должно быть приклеено к краям. Вот как мы можем это исправить:

Центрирование

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

Больше не нужно использовать преобразования position:absolute. Например, мы можем использовать margin:auto для центрирования гибкого элемента как по горизонтали, так и по вертикали.

Меньше абсолютного позиционирования с современным CSS

Соотношение сторон изображения

Новое свойство CSS aspect-ratio теперь поддерживается во всех основных браузерах. Раньше мы использовали отступы, чтобы соблюдать определенное соотношение сторон.

С новым aspect-ratio это намного проще.

Иногда лучше использовать рosition:аbsolute

Меньше абсолютного позиционирования с современным CSS

В этом примере у нас есть контент (аватар, имя и ссылка), перекрывающий обложку карты. У нас есть два варианта реализации этого:

Использовать position:absolute для обложки карты

Использовать отрицательное поле для содержимого

Давайте рассмотрим решения и посмотрим, какое из них больше подходит для этого варианта использования.

Использование абсолютного позиционирования

Меньше абсолютного позиционирования с современным CSS

С помощью этого решения мы можем позиционировать прямоугольник абсолютно, а затем добавить padding:1rem к содержимому карты.

Таким образом, когда покрытие карты убирается, нам не нужно редактировать или изменять CSS.

Меньше абсолютного позиционирования с современным CSS

Использование отрицательных полей

В этом решении карта не будет позиционироваться абсолютно. Вместо этого контент будет иметь отрицательное поле сверху.

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

Меньше абсолютного позиционирования с современным CSS

Обратите внимание, как аватар находится за пределами своего родителя (карты). Чтобы исправить это, нам нужно изменить CSS и удалить отрицательное поле.

В результате — использование position:absolute оказалось лучшим решением, так как избавит нас от написания дополнительных CSS. Надеюсь, вам понравилась статья. Спасибо за чтение!

Автор: Ahmad Shadeed

Источник: ishadeed.com

Редакция: Команда webformyself.

Читайте нас в Telegram, VK, Яндекс.Дзен

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии запрещены.