Shape outside — не стандартные фигуры

видео

Shape outside - не стандартные фигуры

Вступление

Иногда дизайнеры добавляют не очень стандартные элементы в макеты. Ну как на скриншоте ниже:

Скриншот из фигмы, слева круглый элемент который по контуру обтекает текст изнутри и снаружи.
Раздел сайта с круглым элементом. Текст обтекает его плавно по контуру.

Любой элемент в html это прямоугольник. Даже если блоку задать border-radius: 50%;, текст ни при каких условиях не будет обтекать элемент как на скриншоте выше. Будет что-то вроде такого:

Скриншот из фигмы, слева круглый элемент который обтекает текст изнутри и снаружи по прямой линии.
Текст прижимается к левому краю по ровной линии.

Как же добиться эффекта как на первой картинке? Первое, что может прийти в голову — добавить пробелы. Но любое количество пробелов в итоге будут выглядеть как один. Можно обычные пробелы заменить на неразрывные, или добавить тег pre. Но это тоже может повлечь за собой неприятные последствия при изменении текста или при проблемах с загрузкой шрифта. Да и без этого шрифт может немного по-разному отрисовываться вызывая те же последствия.

Shape-outside

Выход есть, но его нужно использовать с осторожностью так как поддержка его оставляет желать лучшего (для моей работы нельзя использовать):

Скриншот с сайта https://caniuse.com/ на котором видно поддержку свойства shape-outside 96.53%.
На момент написания статьи поддержка браузерами составляет 96.53%.

Итак, приступаем к написанию кода, сначала нужно сделать html разметку:

HTML

<!DOCTYPE html>
<html lang="ru">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>shape-outside</title>
  <link rel="stylesheet" href="/css/style.css">
</head>

<body>

  <section class="section">

    <div class="blockquote-wrap">
      <blockquote class="blockquote">
        <span class="blockquote-text">Мы&nbsp;сняли простенький клип на&nbsp;трек &laquo;Inter&raquo;, выложили в&nbsp;сеть. К&nbsp;удивлению, клип набрал сотни тысяч просмотров, с&nbsp;нами связался известный продюссер, предложил свои услуги. С&nbsp;этого все началось.</span>
      </blockquote>

      <span class="blockquote-name">Саша Васильев</span>
    </div>

    <p class="title">Поддерживали ли вас близкие? Изменилось окружение с приходом славы?</p>

    <p class="text">Близкие верили в&#160;нас больше, чем мы&#160;сами. Всегда помогают, поддерживают. Друзья дают советы, как сделать лучше, часто приходят на&#160;концерты, некоторые даже ездят с&#160;нами в&#160;туры по&#160;России. Окружение в&#160;целом не&#160;изменилось, близкие друзья остались с&#160;нами, и&#160;мы&#160;это очень ценим. Конечно, появилось много знакомств, со&#160;знаменитостями, новыми интересными людьми. Но&#160;звездная болезнь обошла нас стороной, мы&#160;до&#160;сих пор воспринимаем все это как сон, не&#160;можем поверить, что это происходит с&#160;нами. Наслаждаемся каждым днем! У&#160;нас с&#160;близкими есть свои традиции, связанные с&#160;нашей работой. Если зовут на&#160;мероприятия, идем с&#160;мамами, сестрами. Им&#160;это интересно, нам нет, радуются, если увидят знаменитость, для них это настоящий праздник. И&#160;нам приятно. Без подержки близких мы&#160;бы не&#160;справились, нам очень с&#160;ними повезло.</p>

  </section>

</body>

</html>

Подключим шрифты и дадим стили для body

CSS

@font-face {
  font-weight: 400;
  font-family: 'Source Sans Pro';
  font-style: normal;
  src: url(../fonts/SourceSansPro-Regular.ttf) format('truetype');
  font-display: swap;
}

@font-face {
  font-weight: 600;
  font-family: 'Source Sans Pro';
  font-style: normal;
  src: url(../fonts/SourceSansPro-SemiBold.ttf) format('truetype');
  font-display: swap;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  margin: 0;
  font-size: 20px;
  font-size: 20px;
  line-height: 140%;
  font-family: 'Source Sans Pro', sans-serif;
  color: #ffffff;
  background-color: #272727;
}

Шрифты я скачал с интернета, но они не как в макете.

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

Первое, что необходимо сделать — добавить размер для section и поставить его горизонтально по центру.

CSS

.section {
  width: 1100px;
  margin: 0 auto;
}

Далее добавим заголовку некоторые стили из макета.

CSS

.title {
  font-weight: 600;
  font-size: 20px;
  color: #7BD7FF;
  margin: 29px 0 20px;
  text-indent: 4px;
}

Ну и можно приступать к блоку с цитатой. Сам blockquote находится в дополнительном контейнере, так как по макету не понятно имя это <cite> или просто текст.

CSS

.blockquote-wrap {
  float: left;
  width: 410px;
  height: 410px;
  margin: 0 14px 0 0;
  text-align: center;
  background-image: url(../img/circle.png);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border-radius: 50%;
}

В целом не вижу смысла описывать каждую строку, но float необходим что бы текст обтекал наш блок. Размеры необходимы фиксированные, так как при изменении размеров блока может поломаться вёрстка. Фоновая картинка нужна что бы блок визуально выглядел как в макете. Ну и border-radius делает наш блок теоретически круглым. Но текст ещё обтекается по ровной линии.

Скриншот выполнения кода, слева блок с кругом, но весь текст выравнивается по ровным линиям.
Текст цитаты выходит за круг, а остальной текст выравнивается по левому краю по ровной линии.

Включаем магию: shape-outside: margin-box;

Теперь текст плавно обтекает цитату, именно по окружности, с учетом заданного magin.

Скриншот выполнения кода, слева блок с кругом, текст который находится справа плавно обтекает цитату.
Текст цитаты выходит за круг, а остальной текст по контуру обтекает круглую цитату.

Но изнутри текст обтекается по прямой линии. Свойство shape-outside работает только в одну сторону. Что бы это поправить переходим к цитате имени и добавляем необходимое:

CSS

.blockquote {
  line-height: 140%;
  margin: 0;
  font-weight: 600;
  font-size: 22px;
}

.blockquote-name {
  display: block;
  margin-top: 30px;
}

Далее можно добавить такое же обтекание только изнутри. Для этого нужно добавить два элемента перед текстом. Либо два HTML элемента, либо два псевдоэлемента.

Так как HTML элементы в разметке простого лендинга не очень хороший тон, сделаю два псевдоэлемента. Не забывая про то что shape-outside может принимать в качестве значения картинку. Как правило, это делается при помощи SVG, но дизайнер всё это дело сделал растровой картинкой, и я её просто разделю на две части.

CSS

.blockquote-wrap::before {
  content: '';
  display: block;
  float: left;
  width: 200px;
  height: 410px;
  shape-outside: url(../img/circle-left.png);
}

.blockquote::before {
  content: '';
  display: block;
  float: right;
  width: 200px;
  height: 410px;
  shape-outside: url(../img/circle-right.png);
}

Осталось повесить сверху кавычки:

CSS

.blockquote-text::before {
  content: '"';
  display: block;
  width: fit-content;
  height: fit-content;
  margin: 0 auto -39px;
  font-weight: 600;
  font-size: 135px;
  line-height: 1;
}

Чуть подправить текст:

CSS

.text {
  max-width: 1000px;
  margin: 0;
}

Можно подгонять всё под пиксель пёрфект.

Скриншот выполнения кода, текст в цитате сохраняет очертания круга, текст который находится справа плавно обтекает цитату.
Весь текст сохраняет очертания круга.

Итоги

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

Объявление

Если вы хотите обучаться вместе со мной, то приглашаю вас на индивидуальные курсы HTML Academy: «Профессиональная вёрстка сайтов» или «Адаптивная вёрстка и автоматизация».

Просто спросите у менеджера меня — наставника Зиновьева Александра. Обучение проходит в помесячном индивидуальном формате, и вы можете начать в любое удобное для вас время.

Кроме того, в HTML Academy вы получите профессию и даже сможете устроиться на работу с новой профессией.