Хабр, привет.

Я сейчас часто обмениваюсь книгами. И так получилось, что мне попалась книга по вёрстке 2004 года. Мне было забавно почитать о техниках, которые были в то время. Я даже вдохновился написать статью. Вот я и здесь.

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

Давайте посмотрим, что я вам подготовил.

Установка размеров элемента

Я думаю, что свойство box-sizing в вашей кодовой базе появляется одним из первых. А знаете ли вы, как рассчитываются размеры элементов без него?

В этой ситуации браузеры будут суммировать свойства width (height), padding и border. Итоговое значение будет являться полной шириной или высотой. Для примера посчитаем размеры у элемента с классом .awesome-block.

.awesome-block {
  width: 990px;
  height: 490px;
  padding: 4px;
  border: 1px solid #222;
}

В итоге ширина будет равняться 1000px, а высота — 500px.

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

Самое страшное было услышать от дизайнера: «Ширина элемента не такая, как в макете». После этих слов приходилось пересчитывать всё, что относилось к этому элементу.

Создание простой сетки

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

А всё потому, что это был целый геморрой. Так ещё приходилось выбирать между двумя плохими вариантами. Первый заключался в использовании свойства float, а второй основывался на свойстве display со значением inline-block.

Давайте рассмотрим каждый способ. Для этого я создам разметку, в которой будет элемент с классом .awesome-container, содержащий пять элементов с классом .awesome-child.

<body>
  <div class="awesome-container">
    <div class="awesome-child">1</div>
    <div class="awesome-child">2</div>
    <div class="awesome-child">3</div>
    <div class="awesome-child">4</div>
    <div class="awesome-child">5</div>
  </div>
</body>

Мы начнём со свойства float. Объявим его со значением left для каждого элемента с классом .awesome-child.

.awesome-child {
  width: 250px;
  height: 300px;
  background-color: #eee;
  margin: 10px;
  
  float: left;
}

Вроде элементы выстроились в две строки. Но не верьте этому. Это ловушка!

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

Высота равняется нулю. Так получилось из‑за особенностей работы свойства float. Дело в том, что оно заставляет браузеры «вытащить» элемент из основного потока страницы. Поскольку мы применили свойство ко всем дочерним элементам, то родитель перестал «видеть» их.

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

В нём объявлялось свойство clear со значением both, которое отменяло действие свойства float. Благодаря ему высота родителя высчитывалась правильно.

Но это не все особенности. Давайте попробуем сделать высоту второго элемента больше.

Да, теперь четвёртый элемент прижался к нему и встал под третьим.

Это вторая особенность свойства float. Элементы всегда стараются притянуться к указанной стороне. Помешать этому может только соседний элемент. Если он есть, то элемент с объявленным свойством float прижмётся к нему. Это произошло в нашем примере.

Из‑за этой особенности каждый фронтендер моего возраста хоть раз сталкивался с проблемой поломанной вёрстки. Если браузеры находили хоть один лишний пиксель, то все элементы сдвигались.

Из‑за одного пикселя даже пятый элемент поменял своё положение. Теперь он находится под четвёртым.

С особенностями свойства float мы закончили. Как я говорил выше, для вёрстки простой сетки можно было ещё использовать свойство display со значением inline-block.

Давайте заменим свойство float на него.

.awesome-child {
  width: 250px;
  height: 300px;
  background-color: #eee;
  margin: 10px;
  
  display: inline-block;
}

Вроде всё хорошо. Элементы отобразились друг за другом в три колонки и два ряда. А теперь я уберу отступы, отключив свойство margin.

Мы получили зазор между элементами. Прикол заключается в том, что он образовался из‑за переноса элементов в разметке. Если написать HTML в одну длинную строку, то его не будет.

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

Например, можно установить родительскому элементу свойство font-size со значением 0.

.awesome-container {
  font-size: 0;
}

Отступ исчез, но и контент тоже. По этой причине требовалось дополнительно объявлять свойство font-size для дочерних элементов.

.awesome-container {
  font-size: 0;
}

.awesome-child {
  width: 250px;
  height: 300px;
  background-color: #eee;
  margin: 10px;
  
  display: inline-block;
  font-size: 16px;
}

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

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

Центрирование элемента по горизонтали и вертикали

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

Давайте представим, что нам надо отцентрировать элемент, у которого объявлено свойство display со значением block. Казалось бы, для этой задачи достаточно использовать свойство margin со значением auto.

<body>
  <div class="awesome-container">
    <div class="awesome-child">Я хочу быть в центре!</div>
  </div>
</body>
.awesome-container {
  width: 850px;
  height: 400px;
  border: 3px solid #222;
}

.awesome-child {
  width: 200px;
  height: 200px;
  background-color: #eee;
	
  margin: auto;
}

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

Одним из способов было поменять значение свойства display с block на inline-block, чтобы можно было использовать свойства позиционирования текста text-align и vertical-align. Также нужно было добавить свойство display со значением table-cell для родителя.

.awesome-container {
  width: 850px;
  height: 400px;
  border: 3px solid #222;

  display: table-cell;
  text-align: center;
  vertical-align: middle;
}

.awesome-child {
  width: 200px;
  height: 200px;
  background-color: #eee;

  display: inline-block;
}

Значение table-cell говорит браузерам: «Этот элемент — ячейка таблицы». После этого свойства text-align и vertical-align могут быть применены.

Как вы видите, логика тут прошла где‑то рядом и ушла в даль.

Центрирование элемента с объявленным свойством position со значением absolute или fixed

Ещё был отдельный метод центрирования элементов с объявленным свойством position со значением absolute или fixed.

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

Для демонстрации разместим элемент посередине окна браузера по горизонтали и вертикали.

<body>
  <div class="awesome-block"></div>
</body>
.awesome-block {
  width: 200px;
  height: 200px;
  padding: 4px;
  border: 1px solid #222;
  background-color: #eee;
	
  position: fixed;
  top: 50%;
  left: 50%;
}

Сейчас в середине находится левый верхний угол элемента.

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

В нашем примере используются свойства top и left. Нам нужно смещать элемент вверх и влево. Это можно сделать с помощью свойств margin-top и margin-left, а в качестве значений использовать половину общей ширины и высоты элемента.

Для этого по очереди нужно суммировать значения свойств width (height), padding и border. Полученное значение поделить на два и записать его со знаком - для свойств margin-top и margin-left.

.awesome-block {
  width: 200px;
  height: 200px;
  padding: 4px;
  border: 1px solid #222;
  background-color: #eee;
	
  position: fixed;
  top: 50%;
  left: 50%;
  
  margin-left: -105px;
  margin-top: -105px;
}

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

Чаще всего я встречал решения с помощью JavaScript и библиотеки jQuery. Потом появилось свойство transform со значением translate(-50%, -50%).

<body>
  <div class="awesome-block">Я хочу быть в центре! Даже когда самый длинный текст</div>
</body>
.awesome-block {
  padding: 4px;
  border: 1px solid #222;
  background-color: #eee;
	
  position: fixed;
  top: 50%;
  left: 50%;
  
  transform: translate(-50%, -50%);
}

В целом это было лучшим решением долгое время. Хотя оно могло вызвать «замыливание» текста на мобильных устройствах, его всё равно использовали.

Создание градиента с помощью свойств background‑image и background‑repeat

Дизайнеры всегда любили делать градиенты. А когда я видел его в макете, то начинал мысленно ныть и материться. Снова нужно было исхитряться. Но, собравшись с духом, я делал свою работу.

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

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

.awesome-block {
  max-width: 960px;
  min-height: 200px;
  background-image: url("gradient.png");
  background-repeat: repeat-x; 
}

Как видите, суть этого метода заключается в том, что с помощью свойства background-repeat и значения x картинка из свойства background-image повторяется по всей ширине элемента.

Заключение

Мы рассмотрели несколько самых распространённых решений по вёрстке, которые были у фронтендера примерно пятнадцать лет назад. Конечно, это не всё. Есть много других.

Я всё хочу рассказать, как верстали скруглённую кнопку. Если вам интересно узнать ещё, то, пожалуйста, напишите в комментариях.

На этом у меня всё. Спасибо за чтение!

P. S. Помогаю больше узнать про CSS и дружелюбные интерфейсы в своих ТГ‑каналах CSS isn't magic и UX + Dev = a11y. Присоединяйтесь. Как вступить, написано в профиле.

© 2026 ООО «МТ ФИНАНС»

Комментарии (6)


  1. metter
    28.07.2026 13:13

    А как же табличная верстка? А как же создание отступов с помощью 0.gif?


    1. DOOMer
      28.07.2026 13:13

      Это надо в статью “Как верстали 25 лет назад”.


  1. jarkevithwlad
    28.07.2026 13:13

    кстати с помощью .vbs скрипта даже на win 11 можно открыть ie

    CreateObject("InternetExplorer.Application").Visible=true
    Скрытый текст


  1. alexchizik
    28.07.2026 13:13

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


  1. pomidoroshev
    28.07.2026 13:13

    Что значит 15 лет назад? Я так до сих пор верстаю


  1. Tzimie
    28.07.2026 13:13

    Зато работало быстрее. А верстка 90х ещё быстрее