Задача про вёрстку баннера

Вы при­хо­ди­те домой, а там Код­зи­ма про­во­дит кон­курс раз­ра­бот­чи­ков «Яндекс-блиц».

Условие

Пред­ставь­те, что вы рабо­та­е­те в Яндек­се и вер­ста­е­те бан­не­ры для реклам­ной систе­мы «Директ». Вы полу­чи­ли зада­ние дора­бо­тать шаб­лон баннера:

Было раньше. 

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

Ста­ло сейчас. 

Дизай­нер решил пере­не­сти кноп­ку в пра­вый ниж­ний угол баннера.

А так нуж­но сделать. 

Исправь­те шаб­лон бан­не­ра, что­бы он соот­вет­ство­вал ново­му маке­ту. Нуж­но, что­бы текст обте­кал кноп­ку сле­ва и свер­ху. Текст бан­не­ра под­став­ля­ет­ся в шаб­лон дина­ми­че­ски и может быть любым. У бан­не­ра все­гда оди­на­ко­вый раз­мер. В шаб­лоне мож­но исполь­зо­вать толь­ко HTML и CSS. Исполь­зо­вать JavaScript и кар­тин­ки нельзя.

Решение

В подоб­ных зада­чах нуж­но вни­ма­тель­но пере­чи­ты­вать усло­вие — оно даёт под­сказ­ку к реше­нию или зада­ёт ход мыс­лей. Пере­чи­ты­ва­ем и выде­ля­ем сле­ду­ю­щие моменты:

  • У бан­не­ра фик­си­ро­ван­ный раз­мер, поэто­му и у кноп­ки, ско­рее все­го, будет посто­ян­ная высота.
  • Текст бан­не­ра обте­ка­е­мый, поэто­му исполь­зу­ем свой­ство float — точ­нее, float: right из-за лево­сто­рон­не­го обтекания.
  • Нуж­но зафик­си­ро­вать кноп­ку вни­зу и сде­лать так, что­бы у тек­ста бан­не­ра был любой раз­мер — это воз­мож­но, если свер­стать кноп­ку перед бло­ком с текстом.

Теперь нуж­но поду­мать, как при­бить кноп­ку к ниж­ней гра­ни­це бан­не­ра. Для это­го под­хо­дят свой­ства margin, transform или «абсо­лют­ное пози­ци­о­ни­ро­ва­ние». Одна­ко если мы при­ме­ним margin, то у нас не сра­бо­та­ет обте­ка­ние свер­ху. Если доба­вить transform, то это не повли­я­ет на макет и сосед­ние эле­мен­ты. «Абсо­лют­ное пози­ци­о­ни­ро­ва­ние» вооб­ще выбьет блок из пото­ка, и это нам точ­но не нужно.

Пере­чи­ты­ва­ем усло­вие и вспо­ми­на­ем, что у бан­не­ра и кноп­ки фик­си­ро­ван­ная высо­та. Это озна­ча­ет, что для верх­ней внут­рен­ней гра­ни­цы бан­не­ра мы можем исполь­зо­вать эле­мент padding-top со зна­че­ни­ем (`<высо­та бан­не­ра> − <высо­та кноп­ки>`) — так мы сдви­нем кнопку.

Про­бле­ма теперь в том, что у нас сдви­ну­лась и кноп­ка, и текст. Что­бы это испра­вить, исполь­зу­ем свой­ство margin-top, кото­рое уме­ет при­ни­мать отри­ца­тель­ное зна­че­ние и сдви­гать эле­мен­ты в обрат­ную сто­ро­ну. Добав­ля­ем к тек­сту margin-top с тем же зна­че­ни­ем, что и padding-top у бан­не­ра, — наш текст воз­вра­ща­ет­ся на место и сохра­ня­ет обте­ка­ние кноп­ки. Гото­во, зада­ча решена:

Итоговый код

<div class="container">
  <a href="#" class="button">Click me!</a>
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
    aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
    sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </div>
</div>
.container {
  background-color: #eee;
  width: 200px;
  height: 120px;
  overflow: hidden;
  font-family: sans-serif;
  font-size: 10px;
  padding-top: 90px;
  box-sizing: border-box;
}
.content {
  margin-top: -90px;
}
.button {
  background-color: orange;
  line-height: 10px;
  padding: 10px;
  box-sizing: border-box;
  display: block;
  color: black;
  text-decoration: none;
  float: right;
}

У этой зада­чи два реше­ния. Мы рас­смот­ре­ли пер­вый вари­ант, кото­рый исполь­зо­вал Давид Рога­нов — фронтенд-разработчик из Яндекс.Практикума, кото­рый в 2018 году решал эту кон­курс­ную зада­чу. Вто­рой вари­ант вы може­те пред­ло­жить в комментариях.