Пособие для начинающих по позиционированию фона в CSS

Пособие для начинающих по позиционированию фона в CSS

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

У элемента может быть более одного фонового изображения. Если вы хотите применить более одного фонового изображения, то можете представить их в виде разделённого запятыми списка значений для свойства background - image . Свойство background - position используется для указания позиции фонового изображения, и это свойство стоит рассмотреть поглубже, т.к. его различные возможные значения приводят к разным результатам, некоторые из которых могут оказаться для вас в новинку, если вы не очень хорошо разбираетесь в CSS.

Мы будем позиционировать одно фоновое изображение во всех примерах, чтобы сохранить код и общие понятия простыми на протяжении всей статьи. Но что подходит для одного фонового изображения, то применимо и ко множественным.

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

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

Области боксовой модели CSS

У элемента в CSS определены три области, называемые боксами: border box (бокс по границы включительно), padding box (бокс по отступу) и content box (бокс по содержимому). border box – область элемента, которая включает всю его внутреннюю часть плюс область, которую занимают сами границы.

Padding box – область элемента, исключающая границу, но включающая контент элемента и окружающие его отступы – указанные при помощи свойства padding .

Content box – область, созданная контентом элемента, исключающая любые отступы и границы.

Области бокса элемента. Изображение взято из CSS-справочника на Codrops, статья про свойство background-origin.

Есть также четвёртая область — «margin box», включающая элемент и его внешние поля, которые указываются при помощи свойства margin .

Когда вы назначаете элементу фон в виде изображения или сплошного цвета, то по умолчанию он закрашивает всю область границы элемента. (Можно изменить это поведение при помощи свойства background - origin , но мы вернёмся к нему в ближайшее время.)

Чтобы указать, где именно внутри области позиционирования будет находиться фоновое изображение, этой области необходима система координат, используемая для преобразования в неё значений background-position. Прежде чем двигаться дальше, давайте повнимательнее рассмотрим эту систему координат.

Система координат элемента

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

У HTML-элемента есть система координат в CSS. У SVG-элементов, напротив, нет похожей системы координат, поскольку они не регламентируются концепцией боксовой модели.

Начальная точка системы координат в CSS расположена в левом верхнем углу элемента.

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

Поскольку по умолчанию областью позиционирования является padding box, то по умолчанию начальной точкой системы координат области позиционирования фона будет верхний левый угол области внутреннего отступа элемента.

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

Например, предположим у вас есть фоновое изображение, применённое к элементу, и вы не задали ему повторение (поэтому применяется только один экземпляр этого изображения). Исходной позицией фонового изображения внутри системы координат будет начальная точка системы координат padding box. Поэтому верхний левый угол изображения позиционируется в верхнем левом углу внутреннего отступа элемента. (См. живой пример ниже.)

К элементу применена полупрозрачная граница в 20px. Заметьте, как изображение позиционируется в верхнем левом углу внутреннего отступа элемента.

Изображение любезно предоставлено Freepik.com

Используя свойство background - position , о котором мы поговорим в этой статье, мы можем изменять позицию изображения внутри этой системы координат.

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

Изменение области позиционирования фона и системы координат при помощи background - origin

Свойство background - origin применяется, чтобы изменить начальную точку системы координат, используемую, чтобы позиционировать фоновое изображение в области позиционирования фона.

Оно принимает одно из трёх значений: padding - box (значение по умолчанию), content - box и border - box .

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

Следующий живой пример показывает разные исходные точки фона/области позиционирования в действии.

Смотрите пример Сары Суэйден (@SaraSoueidan) «Разные значения background-origin» на CodePen.

Для каждой области позиционирования фона, указанной при помощи background - origin , система координат будет сдвигаться, чтобы покрыть эту область.

Затем, в этой системе координат можно указать положение фонового изображения, используя свойство background - position .

Ради простоты, в остальной части этой статьи, мы оставим область позиционирования фона элемента по умолчанию. Поэтому все наши примеры будут применены к элементу, у которого фон позиционируется именно в области отступа.

Позиционирование фоновых изображений при помощи background - position

В прошлом разделе мы видели, как фоновое изображение по умолчанию позиционируется в левом верхнем углу области позиционирования. Это связано с тем, что по умолчанию значение свойства background - position равно 0% 0%.

По умолчанию для background - position используются процентное значение. В background - position можно подставлять либо процентное, либо абсолютное значение, которые указывают смещение изображения от одного из четырёх краёв области позиционирования (вверх, право, низ, лево)

Углы смещения элемента и система координат в CSS.

В дополнение к процентным и абсолютным значениям, для смещения можно использовать ещё и пять ключевых слов: top , right , bottom , left и center .

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

Если вы укажите только одно значение, то второе будет считаться, как center . Если укажите два значения, то первое будет определять смещение от левого угла — т.е. горизонтальную позицию, а второе – смещение вниз от верхнего угла — вертикальную позицию.

Можно смешивать и сочетать значения, комбинируя длину с процентами и/или ключевыми словами. Заметьте, что пару ключевых слов можно поменять местами, тогда как комбинацию ключевого слова и длины либо процентов — нельзя. Поэтому center left — правильная запись, а 50% left — нет, она должна выглядеть так: left 50% . При комбинировании ключевого слова и длины или процентного значения, первое значение всегда отвечает за горизонтальное смещение, а второе — за вертикальное.

Собственно говоря, ключевое слово – это сокращённая запись для определённых процентных значений. Точнее сказать: top — смещение 0% от верхнего края, bottom — смещение 100% от верхнего края, left — смещение 0% от левого края, right — смещение 100% от левого края, а center — смещение 50% в том направлении (горизонтальном или вертикальном), к которому оно применяется.

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

Как работают абсолютные значения background-position

При указании значения в абсолютных единицах, вы смещаете верхний угол фонового изображения на указанное число. Другими словами, изображение передвинется так, чтобы его верхний левый угол позиционировался на указанные в значении background - position смещения.

Лучший способ объяснить и понять это – показать наглядно, поэтому здесь представлено два примера абсолютных значений позиции фона и то, как браузеры реализуют позиционирование фонового изображения при помощи абсолютных значений. Элементу в этих двух примерах задан размер 100px на 80px.

Позиционирование фонового изображения при помощи абсолютных значений.

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

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

Попробуйте изменить значения позиции фона в следующем живом примере, чтобы увидеть, как оно влияет на изображение. И обязательно попробуйте отрицательное значение!

Как работают процентные значения background-position

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

Например, процентное значение 0% 0% выровняет точку 0% 0% изображении с точкой 0% 0% в системе координат области позиционирования фона. Значение 50% 75% свойства background-position выровняет точку, которая находится в 50% от левого и в 75% от верхнего края изображения с точкой, которая расположена на 50% 75% в области позиционирования фона.

И снова, лучше объяснит наглядный пример. Заметьте, как указанное значение background-position используется, чтобы получить точку этих координат внутри изображения, а затем выравнивает эту точку с точкой в тех же координатах в области позиционирования.

Позиционирование фонового изображения при помощи процентных значений..

Как и с абсолютными единицами длины, можно указать процентное смещение в отрицательных значениях, и они передвинут фоновое изображение на указанное значение в противоположенном направлении на соответствующей оси. Поэтому значения -10% -30% сместят изображение на 10% влево от левого края и на 30% вверх.

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

Позиционирование в предыдущих двух примерах делается относительно верхнего и левого краёв. Теперь давайте посмотрим, как можно объединить ключевые слова вместе с численными значениями смещения (процентами или абсолютными единицами), чтобы позиционировать изображения вдоль области позиционирования фона относительно любого из четырёх краёв элемента.

Смещение относительно любого края

В примерах из предыдущих двух разделов мы указывали смещения и видели, как они используются, чтобы переместить изображение относительно верхнего и левого края — т.е. поведение по умолчанию для одного или двух значений background - position .

Когда мы объединяем в четырёхзначный синтаксис ключевые слова для смещения с численными значениями, мы также можем сместить фоновое изображение от правого и нижнего краёв области позиционирования.

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

Например, в следующем примере используется четырёхзначный синтаксис:

Если указано три из четырёх значений, четвёртое значение приравнивается к нулю.

При использовании четырёхзначного синтаксиса следует кое-что помнить: когда приведено три или четыре значения, тогда каждое процентное значение или длина представляют смещение и должны идти за ключевым словом, указывающим край, от которого должно смещаться фоновое изображение. Например, background - position : bottom 10 px right 20 px представляет вертикальное смещение на 10px вверх от нижнего края и горизонтальное смещение на 20px влево от правого края. Если указано три значения, недостающее смещение приравнивается к нулю. Если вы укажите два численных смещения и одно ключевое слово, то такое значение будет неверным и браузер использует 0% 0% — значение по умолчанию.

Чтобы лучше это понять, поиграйтесь со значениями свойства background - position в следующем живом примере. Для лучшего понимания фоновое изображение сначала позиционируется так, чтобы оно смещалось на 0 пикселей от нижнего и 2em от правого края.

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

Установка размеров, повторение, обрезка изображений и многое другое!

Помните, что можно к элементу можно применять множественные фоновые изображения. Для каждого фонового изображения (представленных в виде списка изображений, разделённого запятыми в background - image ) можно указать соответствующую фоновую позицию; множественные позиции также разделяются запятыми.

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

Кроме того, теперь, помимо основных свойств для фона, есть и дополнительные свойства, которые позволяют применять к фоновым изображениям эффекты наложения, похожие на эффекты, доступные в редакторах типа Photoshop — в частности, свойство background - blend - mode . Если вам интересно изучить всё о наложении в CSS, то можете прочитать об этом в этой статье.

Я надеюсь, что эта статья оказалась для вас полезной. Спасибо за чтение.

P.S. Это тоже может быть интересно:

Если вам понравилась статья, поделитесь ей!

9 комментариев

Ошибка во второй картинке (где background-position: 50px(horizontal offset) 30px(vertical offset);): Как работают абсолютные значения background-position.

Можете уточнить, где именно ошибка? По-моему, всё корректно (на горизонтальной оси отметка 50px, на вертикальной — 30px). В оригинале статьи так же…

Вопрос исчерпан, прошу извинить, все правильно. Стрелки смутили (точнее их направление). Немного сбивает с толку такая визуализация расстояний (стрелка смотрит вниз и кажется, что первое значение не горизонтальное а вертикальное)

Если честно, столкнулся с тем, что несмотря на то, что алгоритм заполнения фон, довольно интересный, его применение в синтаксисе, мне показалось совсем не интуитивным, поэтому хотелось бы отметить это подробней. Возьмём такой, не замысловатый пример: background: radial-gradient(#f2f780, #254821 70%, #ffaecd 100%) 130% 0% / 200% 100%; Вроде, без особого труда ясно, что через слэш представлены значения background-position / background-size (перечислены значения по координатам X и Y), давайте посмотрим как они работают во взаимодействии при различных значениях. Отмечу, что радиальный градиент идёт по-умолчанию из центра (что легко меняется), то есть, из точки 50% 50%. Для простоты менять не будем. В нашем случае, по оси X размер градиента 200%, и центр исхождения световых слоёв будет находится посередине, то есть, на 100% по горизонтальной координате, центр — на краю левой стороны экрана. При этом градиент, по-умолчанию, идёт до дальнего угла изображения, в случае, когда градиент расположен по центру, до 100% края градиента доходят его углы в равной степени. По горизонтали и по вертикали градиент заканчивается задолго до 100% своего исхождения что видно на иллюстрации. Градиент как бы обрезается горизонтальными и вертикальными рамками, вписывается в прямоугольное окно и только в углах виден весь его спектр. Поскольку точка исхождения находится посередине, то левые и правые стороны находятся на одинаковом расстоянии от центра, поэтому «новый градиент» начинается с того же фона, на котором заканчивается текущий. Этими плитками заполняется виртуальное пространство. В этой статье очень хорошо описан принцип расположения фоновых изображений: точка 70% изображения и видимой части экрана (браузера) совпадёт. Такой, довольно интересный принцип позволяет плавно сдвигать изображения так, чтоб 0% — изображение прижато к левому краю, 100% — к правому (точно такой же принцип может быть применён и для верха/низа). В результате 50% изображение будет в середине, 30%/70% — пропорционально ближе к левой/правой части экрана соответственно. Тем не менее, нужно понять, как это принцип применяется, в частности, в таком, как оказалось не простом случае, как радиальный градиент. В случае, когда градиент меньше размер экрана, он ведёт себя так, как описано в статье — перемещается влево/вправо по описанному выше алгоритму, свободные участки же заполняются другими градиентами. Когда backgrond-size составляет 100%, то, понимая приведённый выше алгоритм лёгко понять, что background-position просто не работает, поскольку любая точка изображения совпадает с аналогичной точкой экрана, а поскольку любое позиционирование фона, это синхронизация изображения и экрана в определённой точке, то, поскольку все точки уже синхронизированы, то и перемещаться просто нечему (в случае когда backgrond-size равен 100% только по определённой координате, то изображение, соответственно не двигается по этой координате, но может двигаться по другой). Понимание, что 100% экрана — это окно, а изображение попадает в это окно синхронизируясь с ним в точке указанной в background-position, можно понять и случаи когда фоновое изображение больше чем экран, а также как позиционируются точки большие, чем 100%. Ну, во-первых, установим в указаном выше примере для background значения 100% 0% / 200% 100%, то есть, по оси X у нас background-size: 200%, а background-position: 100%. Что мы видим? Окончание горизонтальной части градиента совпадает с концом экрана (то есть самая левая точка градиента, совпадает с самой левой точкой экрана). При этом видно, что градиент больше размера экрана, и, поскольку больше он в два раза (200%), то середина градиента находится ровно в начале экрана, на его левой стороне. Нам понадобилось бы два экрана, чтоб отобразить градиент целиком, второй (виртуальный) экран должен расположиться слева. Итак, берём точку 100% у изображения, синхронизируем её с аналогичной точкой экрана(в данном случае 100%), а дальше уже в единицах измерения экрана отмеряем видимую часть. Так что же будет если background-position окажется больше 100%? Рассмотрим, как раз случай данный в самом начале: 130% 0% / 200% 100%. Нас понятно интересуют значения по X, 200% размер градиента, 130 — позиционирование. Что означает эта запись? размер градиента, понятна, равен двум экранам. И, внимание, точка, находящаяся на 130% градиента, совпадает со 130% точкой экрана. То есть, точка синхронизации уходит за размеры экрана и расположена на виртуальном экране справа. Что получается? Берём точку 130% от 200-процентного градиента, это 260%. Эта точка совпадает со 130% точкой экрана. Соответственно убираем 30% виртуального экрана, у нас получается 230% это правый край экрана 130% левый край. Размер градиента — 200%, значит начнётся экран с угасания градиента на 130% точке (центр-то на 100%) дойдёт до 200% перейдёт в следующий градиент (градиенты идут последовательно один за другим заполняя виртуальное пространство, отображаясь там куда мы «притащим» наш экран), так вот в 200% точке один градиент кончится и начнётся другой, который пройдёт к центру ровно 30% экрана. Вот, пожалуй, и всё — так они и заполняются :-)

На мой взгляд, не вполне интуитивно, как работают абсолютные и относительные размеры в сочетании. В том же примере ставим, например: background: radial-gradient(#f2f780, #254821 70%, #ffaecd 100%) 130% calc(20% + 2em) / 200% 100%;

Ведь выяснилось же, что фон при background-size: 100% не сдвигается, потому как экран и изображения синхронизированы в каждой точке. Поэтому кажется, что в точке 20% + 2em всё будет тоже самое. Но на деле, background-size: 100%, а background-position: calc(20% + 2em) у нас всё по горизонтальной координате сдвигается вниз на 2em. В данном случае 20% ни на что ни влияют, мы можем поставить любое значение или вообще убрать calc и поставить 2em, ничего не изменится. Когда стоит значение без процентов, не изменится сдвиг, и если мы background-size поставим 200%. Получается у нас как бы два измерения: позиционирование (это я так назвал подгонку фона под проценты экрана), измеряемое в процентах и зависит от background-size и абсолютные значения, которые ни от чего не зависят. В принципе, в этом просматривается довольно стройная логика и возможности конкретного сдвига и тонкой подстройки в соответствии с экраном. Но в тоже время когда и то, и другое используется в одной и той же настройке, эта логика, на мой взгляд, не вполне прозрачна…

Возможно, удобнее будет рассматривать проценты в background-position как проценты от разницы между размером блока и размером фона — так сказать, «от оставшегося доступного места» (и считать их от левого верхнего угла блока до левого верхнего угла фона). Результат тот же, но так может быть нагляднее. Тогда сразу видно, что при background-size:100% любое количество процентов от «доступного места» равно нулю, поэтому и не влияет на общую сумму в calc() . А при background-size больше 100% эта разница оказывается отрицательной, и проценты от нее, соответственно, тоже — поэтому с положительным значением в процентах фон тогда смещается за край контейнера наружу.

Тут ещё есть вот какой момент, когда мы ТАК, двигаем градиент, у нас может получиться как в первом шарике вот этой иллюстрации — градиент «не дотягивается» до края шара, поскольку «прямоугольник мозаики» его обрезает. Можно, наверное, делать и через background-size (хотя зачем там calc, впрочем с ним, пожалуй, нагляднее). Но так вообще, подобный синтаксис, без комментариев разработчика, в некотором роде, вносит некоторую путаницу, когда стараешься его понять, и выяснить, что вообще за что отвечает. Создаётся впечатление, что эти 50% что-то решают (а они ничего не решают, пока background-size: 100%, то является значением по-умолчанию). И центр градиента, вроде как, устанавливается этими 50% calc(50% + 2em), тогда как градиент они вообще не трогают, а двигают фон. Но ведь можно двигать и градиент! И, возможно, это более точное решение, поскольку меняет именно те параметры, которые отвечают за нужные нам свойства… По поводу «оставшегося свободного места» — согласен, довольно интуитивная идея. Двигаем на оставшуюся разницу :) Есть фон и есть экран, насколько в процентах сдвигается одно, настолько двигается и другое. А на получившуюся разницу в абсолютных величинах, сдвигается центр фона. Если проведём радиус из центра экрана до синхронизируемой точки, то центр фона будет располагаться на прямой, построенной через эти две точки. Если фон меньше, то и радиус у него меньше чем у экрана, и его центр из исходной точки «не дотягивается» до центра экрана. Если фон = экрану, то центры совпадают. Если радиус фона больше, то центр фона уходит в противоположную сторону. Легко увидеть на той же иллюстрации/a>, установив значения (после градиента) в 100% 0% / 200% 100%, то есть, сделав фон в два раза больше экрана. Можно увидеть куда фон «уйдёт». Ну и далее, поигравшись со значениями и усвоить как движется фон, относительно экрана.

Хм, жаль сообщения нельзя редактировать :-) Увидел пару неточностей, но надеюсь, Вы поймёте где о чём идёт речь…

📎📎📎📎📎📎📎📎📎📎