Круг в центре прямоугольника — задача для radial-gradient():

.flag--japan {
  aspect-ratio: 3 / 2;
  background: radial-gradient(circle closest-side, #bc002d 60%, #fff 0);
}

Синтаксис стопов тот же, что у линейного градиента: красный до 60%, дальше сразу белый. Новое здесь — слова circle и closest-side. Разберём, зачем они.

Как работает радиальный градиент

Цвета расходятся из одной точки во все стороны, как круги на воде. Позиция 0% — центр, а 100% — граница фигуры, которую градиент «надувает» вокруг центра.

По умолчанию:

  • центр — середина блока;
  • форма — эллипс (ellipse), вытянутый вместе с блоком;
  • размер — farthest-corner: граница 100% проходит через самый дальний от центра угол блока.

Поэтому radial-gradient(red 50%, white 0) на прямоугольном блоке рисует не круг, а овал.

Форма и размер

Перед списком цветов можно указать форму и размер — в любом порядке:

  • circle — всегда круг, независимо от пропорций блока;
  • closest-side — 100% достают до ближайшей стороны блока;
  • farthest-side — до самой дальней стороны;
  • closest-corner и farthest-corner — до ближайшего и дальнего угла.
.box--default        { background: radial-gradient(#e64980 50%, #ffe3e3 0); }
.box--circle         { background: radial-gradient(circle, #e64980 50%, #ffe3e3 0); }
.box--closest        { background: radial-gradient(closest-side, #e64980 50%, #ffe3e3 0); }
.box--circle-closest { background: radial-gradient(circle closest-side, #e64980 50%, #ffe3e3 0); }

Теперь флаг Японии читается целиком. У флага 3:2 ближайшие стороны — верхняя и нижняя, значит, 100% круга — это половина высоты. Красный занимает 60% радиуса, то есть диаметр круга — 60% высоты флага, как и положено по пропорциям.

Размер можно задать и числами: circle 40px или ellipse 50% 30%. Есть тонкость: у круга радиус задаётся только длиной (px, em и т. п.), проценты разрешены лишь у эллипса — по одному на каждую полуось. Поэтому для резинового круга ключевые слова вроде closest-side удобнее чисел.

Центр не посередине

Положение центра задают после формы и размера, через at — так же, как background-position: at 30% 50%, at left top, at 20px 40px.

У флага Бангладеш круг чуть сдвинут влево: его центр на 45% длины.

.flag--bangladesh {
  aspect-ratio: 5 / 3;
  background: radial-gradient(circle closest-side at 45% 50%, #f42a41 66.67%, #006a4e 0);
}

Почему здесь closest-side, а не размер по умолчанию? При сдвинутом центре расстояние до самого дальнего угла меняется, и пришлось бы считать его по теореме Пифагора. А ближайшими по-прежнему остаются верх и низ, так что 100% — это всё та же половина высоты. Радиус круга по пропорциям флага — 2/3 от неё, отсюда 66.67%.

Не только флаги: мягкое свечение

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

.hero {
  background:
    radial-gradient(ellipse 70% 60% at 50% 0%, #4dabf788, #0000 70%),
    #0b1220;
}

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

Что запомнить

  • По умолчанию радиальный градиент — эллипс до дальнего угла с центром посередине.
  • circle делает круг, closest-side и компания задают, до чего тянутся 100%.
  • Центр сдвигают через at; при сдвиге выгоднее брать размер, привязанный к сторонам.