Неизведанные глубины CSS: метрики шрифта, line-height и vertical-align

Перевод статьи Deep dive CSS: font metrics, line-height and vertical-align с сайта iamvdo.me, опубликовано на css-live.ru с разрешения автора — Венсана де Оливейры.

Line-height и vertical-align — простые CSS-свойства. Настолько простые, что большинство из нас уверены, что понимают, как они работают и как ими пользоваться. Но это не так. На деле они сложны, может быть, самые сложные, потому что у них ведущая роль в создании одной из наименее известных особенностей CSS: строчного (инлайнового) контекста форматирования.

Например, line-height можно задать в виде длины или безразмерного значения 1, но по умолчанию у него значение normal — «нормально». Прекрасно, но что значит «нормально»? Часто пишут, что это (по крайней мере, должно быть) 1, или где-то 1.2, даже CSS-спецификация не дает точного ответа. Мы знаем, что безразмерное  line-height считается относительно font-size, но загвоздка в том, что font-size: 100px ведет себя по-разному для разных гарнитур, так будет ли line-height всегда одинаковым или разным? Действительно ли оно от 1 до 1.2? А vertical-align, как line-height влияет на него?

Давайте углубимся в не самый простой CSS-механизм…

Поговорим сначала о font-size

Взгляните на этот простой HTML-код, тег <p> с 3 <span>-ами внутри, все с разными font-family:

<p>
    <span class="a">Ba</span>
    <span class="b">Ba</span>
    <span class="c">Ba</span>
</p>
p  { font-size: 100px }
.a { font-family: Helvetica }
.b { font-family: Gruppo    }
.c { font-family: Catamaran }

Одинаковый font-size с разными гарнитурами дает элементы разной высоты:


Разные гарнитуры, одинаковый font-size, разная высота в итоге

Даже знай мы эту особенность, почему font-size: 100px не делает элементы высотой 100px? Я измерил эти значения: Helvetica — 115px, Gruppo — 97px и Catamaran — 164px.


Высота элементов с font-size: 100px колеблется от 97px до 164px

Хотя на первый взгляд это странно, это вполне ожидаемо. Причина в самом шрифте. Вот как это работает:

  • шрифт задает свои единицы измерения em-квадрата (или UPM, units per em — единиц на кегль), некий контейнер, в котором будут рисоваться все символы. В этом контейнере всё измеряется в относительных единицах и обычно он принимается за 1000 единиц. Но бывает и 1024, и 2048, и сколько угодно.
  • на базе этих относительных единиц задаются метрики шрифта: высота верхних выносных элементов (ascender), нижних выносных (descender), заглавных букв (capital height), строчных букв (x-height) и т.п. Заметьте, что некоторые значения могут выступать за рамки em-квадрата.
  • в браузере эти относительные единицы масштабируются до заданного font-size.

Возьмем шрифт Catamaran и откроем его в FontForge, чтобы увидеть метрики:

  • em-квадрат принят за 1000 единиц
  • высота верхних выносных — 1100, а нижних — 540. Судя по нескольким тестам, браузеры используют значения HHead Ascent/Descent на Mac OS и Win Ascent/Descent на Windows (и эти значения могут различаться!). Также видно, что Capital Height равна 640, а X height — 485.


Значения метрик шрифта в FontForge

Это значит, что шрифт Catamaran использует 1100 + 540 единиц из em-квадрата в 1000 единиц, что при font-size: 100px дает высоту 164px. Эта вычисленная высота определяет область содержимого элемента, так я и буду называть ее всю статью. Можете представлять область содержимого как ту область, к которой применяется свойство background 2.

Также легко предсказать, что высота заглавных букв будет 68px (680 единиц), а строчных (x-высота) — 49px (485 единиц). Как результат, 1ex = 49px, а 1em = 100px, а не 164px (к счастью, em отсчитывается от font-size, а не от вычисленной высоты)


Шрифт Catamaran: единицы на em (UPM) и их эквиваленты в пикселях при font-size: 100px

Прежде чем дальше лезть вглубь, вкратце рассмотрим основные понятия, с которыми предстоит иметь дело. Когда элемент <p> отображается на экране, он может состоять из нескольких строк, занимающих доступную ширину.  Каждая строка набирается из нескольких элементов строки (HTML-тегов или анонимных элементов строки для текстового содержимого) и называется контейнером строки (line-box). Высота контейнера строки определяется высотами его потомков. Таким образом, браузер рассчитывает высоту каждого элемента строки, а по ней — высоту контейнера строки (от самой высокой до самой низкой точки ее потомков). В итоге высоты контейнера строки всегда хватает, чтобы вместить всех его потомков (по построению).

Каждый HTML-элемент на самом деле представляет собой «стопку» контейнеров строки. Если вы знаете высоту каждого контейнера строки, вы знаете и высоту элемента.

Если мы изменим предыдущий HTML-код вот так:

<p>
    Good design will be better.
    <span class="a">Ba</span>
    <span class="b">Ba</span>
    <span class="c">Ba</span>
    We get to make a consequence.
</p>

Он сгенерирует 3 контейнера строки:

  • в первом и последнем — только по одному анонимному элементу строки (текст)
  • во втором — два анонимных элемента строки и 3 <span>


Элемент <p> (черная рамка) состоит из контейнеров строк (белые рамки), состоящих из строчных элементов (сплошные рамки) и анонимных элементов строки (пунктирные рамки)

Хорошо видно, что второй контейнер строки выше остальных, из-за вычисленной области содержимого его потомков, а точнее — того, что со шрифтом Catamaran.

Самое сложное в создании контейнера строки то, что мы не можем ни толком это увидеть, ни управлять этим из CSS. Даже задание фона для ::first-line не помогает представить высоту первого контейнера строки наглядно.

line-height: до подводных камней и дальше

До сих пор я ввел два понятия: область содержимого и контейнер строки. Если вы читали внимательно, я сказал, что высота контейнера строки рассчитывается по высоте его потомков, я не говорил «высоте области содержимого потомков». И в этом большая разница.

Хоть это может прозвучать странно, у элемента строки есть две разных высоты: высота области содержимого и высота виртуальной области (я придумал термин «виртуальная область», потому что эта высота нам не видна, но в спецификации вы нигде этого термина не найдете).

  • высота области содержимого определяется метриками шрифта (как мы видели раньше)
  • высота виртуальной области — это line-height, и именно эта высота используется при расчете высоты контейнера строки


У элементов строки есть две разные высоты

Помимо прочего, это опровергает популярное представление, что line-height — это расстояние между базовыми линиями шрифта. В CSS это не так 3.


В CSS line-height — не расстояние между базовыми линиями

Вычисленная разность высот между виртуальной областью и областью содержимого называется «leading», или интерлиньяж (прим. перев.: в некоторых русскоязычных источниках «интерлиньяжем» называют саму «высоту виртуальной области» в терминах Венсана, что часто приводит к путанице. Интересно, что во французской версии статьи Венсан использует тоже англоязычный термин «leading»). Половина интерлиньяжа добавляется сверху от области содержимого, вторая половина снизу от нее. Таким образом, область содержимого всегда будет посередине виртуальной области.

В зависимости от вычисленного значения, line-height (виртуальная область) может быть равна, выше или ниже области содержимого. Если виртуальная область ниже, то интерлиньяж отрицательный и контейнер строки визуально оказывается ниже собственных потомков.

Есть и другие виды элементов строки:

  • замещаемые элементы строки (<img>, <input>, <svg> и т.п.)
  • элементы типа inline-block и прочих inline-*
  • строчные элементы, участвующие в особых контекстах форматирования (например, во флекс-контейнере все флекс-элементы «облочняются»)

Для этих особых строчных элементов высота рассчитывается по их свойствам height, margin and border. Если у height значение auto, то используется line-height, и высота области содержимого строго равна line-height.


У замещаемых строчных элементов, элементов типа inline-block/inline-* и «облочненных» строчных элементов высота области содержимого равна их высоте, или line-height.

Как бы то ни было, мы до сих пор не решили проблему, чему же равно значение normal у line-height? И ответ, как и при расчете высоты области содержимого, надо искать в метриках шрифта.

Вернемся в FontForge. Размер em-квадрата для шрифта Catamaran равен 1000, но мы видим много других значений для верхних/нижних выносных и не только:

  • общие значения Ascent/Descent: высота верхней части равна 770, а нижней — 230. Используется для отрисовки символов (табличка «OS/2»).
  • метрики Ascent/Descent: 1100 вверх и 540 вниз. Используется для высоты области содержимого (таблички «hhea» и «OS/2»)
  • метрика Line Gap («межстрочный зазор»). Используется для line-height: normal, данное значение прибавляется к метрикам Ascent/Descent (табличка «hhea»)

В нашем случае шрифт Catamaran определяет межстрочный зазор в 0 единиц, так что line-height: normal будет равна высоте области содержимого, т.е. 1640 единиц или 1.64.

Для сравнения, в шрифте Arial em-квадрат взят за 2048 единиц, высота верхней части — 1854, нижней части — 434, а межстрочный зазор — 67. Это значит, что при font-size: 100px высота области содержимого будет 112px (2288/2048≈1,117), а line-height: normal — 115 px (2355/2048≈1.15). Все эти метрики специфичны для каждого шрифта и заданы дизайнером-шрифтовиком, который его создал.

Становится очевидно, что указывать line-height: 1 — плохой подход. Напоминаю, что безразмерные значения отсчитываются от font-size, а не от области содержимого, и немало проблем возникает от того, что виртуальная область оказывается меньше области содержимого.


Из-за line-height: 1 контейнер строки может стать ниже, чем область содержимого

Но не только line-height: 1. Например, из 1117 шрифтов, установленных на моем компьютере (да, я установил все шрифты из Google Web Fonts) у 1059, это около 95%, вычисленная line-height больше 1. Вообще вычисленная line-height у них колеблется от 0.618 до 3.378. Вам не померещилось, 3.378!

Немного подробностей о расчете контейнера строки:

  • для строчных элементов padding и border увеличивают область фона, но не область содержимого (и не высоту контейнера строки). Так что не всегда область содержимого — то, что видно на экране. А margin-top и margin-bottom ни на что не влияют.
  • для замещаемых строчных элементов, элементов типа inline-block и «облочненных» строчных элементов: padding, margin и border увеличивают height, а значит, и высоту области содержимого и контейнера строки.

vertical-align: одно свойство, чтоб править всеми

Я еще не упоминал свойство vertical-align, хотя оно существенно влияет на расчет высоты контейнера строки. Мы даже можем сказать, что vertical-align может играть ведущую роль в строчном контексте форматирования.

По умолчанию у него значение baseline. Помните метрики шрифта «ascender» и «descender» (верхняя и нижняя части)? Они определяют, где находится базовая линия, т.е. в какой пропорции она делит символ на верхнюю и нижнюю части (как ватерлиния корабля делит его на надводную и подводную части — прим. перев.). Поскольку пропорция между верхней и нижней часть редко бывает 50/50, это иногда приводит к неожиданным результатам, например, с соседними элементами.

Начнем с такого кода:

<p>
    <span>Ba</span>
    <span>Ba</span>
</p>
p {
    font-family: Catamaran;
    font-size: 100px;
    line-height: 200px;
}

Тег <p> с двумя соседними <span>-ами, наследующими font-family, font-size и фиксированный line-height. Базовые линии совпадают и высота контейнера строки равна их line-height.


Тот же шрифт, та же базовая линия, на вид всё в порядке

Что, если у второго элемента будет меньший font-size?

span:last-child {
    font-size: 50px;
}

Как бы странно это ни звучало, из-за выравнивания по базовой линии (по умолчанию) контейнер строки может стать выше (!), как показано на рисунке внизу. Напоминаю, что высота контейнера строки рассчитывается от самой высокой до самой низкой точки его потомков.


Меньший дочерний элемент может привести к большей высоте контейнера строки

Это может быть аргументом в пользу безразмерных значений line-height, но иногда для создания идеального вертикального ритма требуются фиксированные. Сказать честно, что бы вы ни выбрали, с выравниванием в строке всегда будут неприятности.

Вот другой пример. Тег <p> с line-height: 200px, а в нем единственный <span>, наследующий его line-height

<p>
    <span>Ba</span>
</p>
p {
    line-height: 200px;
}
span {
    font-family: Catamaran;
    font-size: 100px;
}

Какой высоты будет контейнер строки? Можно подумать, что 200px, но не тут-то было. Проблема в том, что у этого <p> своё, другое значение font-family (по умолчанию оно serif). Положение базовой линии у <p> и у <span> наверняка разное, поэтому высота контейнера строки больше, чем ожидалось. Это потому, что браузеры считают так, как будто каждый контейнер строки начинается с символа нулевой ширины, который спецификация называет термином «strut».

Символ невидимый, но влияние заметное

Итого, перед нами та же проблема, что в прошлом примере с соседними элементами.


Каждый потомок выравнивается так, как будто его контейнер строки начинается с символа нулевой ширины

Выравнивание по базовой линии пролетает, но, может быть, vertical-align: middle нас спасет? Как гласит спецификация, значение middle «выравнивает вертикальную середину бокса с базовой линией родительского бокса плюс половина родительской x-высоты». Положение базовых линий бывает разное, x-высота — тоже, так что и на middle положиться нельзя. Хуже всего то, что в большинстве сценариев middle никогда не бывает по-настоящему «посередине». Слишком много всего влияет и это нельзя прописать в CSS (x-высота, относительное положение базовой линии и т.п.)

Отмечу, что есть еще 4 значения, полезные в некоторых случаях:

  • vertical-align: top / bottom выравнивают по верху или низу контейнера строки
  • vertical-align: text-top / text-bottom выравнивают по верху или низу области содержимого


Vertical-align: top, bottom, text-top и text-bottom

Но будьте осторожны: во всех случаях оно выравнивает виртуальную область, высота которой невидима. Взгляните на этот простой пример с vertical-align: top. Невидимая line-height может давать странные, хотя и предсказуемые, результаты.


vertical-align может давать на первый взгляд странный результат, хотя, если наглядно представить line-height, всё ожидаемо

Наконец, vertical-align принимает также числовые значения, которые поднимают или опускают бокс относительно базовой линии. Этот последний вариант часто может выручить.

«CSS is awesome»

Мы поговорили о взаимодействии line-height и vertical-align, но вопрос-то вот в чем: можно ли управлять метриками шрифта из CSS? Короткий ответ: нет. Хотя я очень на это надеялся. Как бы то ни было, думаю, пора нам немного поразмяться. Метрики шрифтов — константы, что-то же у нас в любом случае получится.

Что если, например, нам нужен текст шрифтом Catamaran, в котором заглавные буквы будут ровно 100px высотой? С виду осуществимо: давайте немного посчитаем.

Первым делом укажем все метрики шрифта в виде пользовательских свойств CSS 4, затем рассчитаем, при каком font-size заглавные буквы будут высотой 100px.

p {
    /* метрики шрифта */
    --font: Catamaran;
    --capitalHeight: 0.68;
    --descender: 0.54;
    --ascender: 1.1;
    --linegap: 0;

    /* нужная высота заглавных букв */
    --fontSize: 100;

    /* apply font-family */
    font-family: var(--font);

    /* рассчитываем font-size для получения нужной высоты заглавных букв */
    --computedFontSize: (var(--fontSize) / var(--capitalHeight));
    font-size: calc(var(--computedFontSize) * 1px);
}


Теперь заглавные буквы высотой 100px

Достаточно очевидно, правда? Но что если мы  хотим вертикально отцентрировать текст, чтобы свободное место поровну распределялось сверху и снизу от буквы «B»? Чтобы добиться этого, придется рассчитать vertical-align на основе положения базовой линии (пропорции верхней/нижней частей).

Сначала рассчитаем величину line-height: normal и высоту области содержимого:

p {
    …
    --lineheightNormal: (var(--ascender) + var(--descender) + var(--linegap));
    --contentArea: (var(--lineheightNormal) * var(--computedFontSize));
}

Затем нам понадобятся:

  • расстояние от низа заглавной буквы до нижнего края
  • расстояние от верха заглавной буквы до верхнего края

Примерно так:

p {
    …
    --distanceBottom: (var(--descender));
    --distanceTop: (var(--ascender) - var(--capitalHeight));
}

Теперь можно рассчитать значение vertical-align, которое будет равно разнице этих расстояний, умноженной на вычисленное значение font-size (нам надо будет применить это значение к строчному дочернему элементу).

p {
    …
    --valign: ((var(--distanceBottom) - var(--distanceTop)) * var(--computedFontSize));
}
span {
    vertical-align: calc(var(--valign) * -1px);
}

И в конце зададим желаемую высоту строки и вычислим соответствующий line-height так, чтобы вертикальное выравнивание сохранилось:

p {
    …
    /* желаемая высота строки */
    --lineheight: 3;
    line-height: calc(((var(--lineheight) * var(--fontSize)) - var(--valign)) * 1px);
}


Результаты для разных line-height. Текст всегда посередине.

Теперь легко добавить иконку одной высоты с буквой «B»:

span::before {
    content: '';
    display: inline-block;
    width: calc(1px * var(--fontSize));
    height: calc(1px * var(--fontSize));
    margin-right: 10px;
    background: url('https://cdn.pbrd.co/images/yBAKn5bbv.png');
    background-size: cover;
}


Иконка и буква «B» равны по высоте

Посмотреть результат в JSBin

Учтите, что этот тест только для демонстрационных целей. Полагаться на это нельзя. Причин много:

  • метрики шрифтов-то постоянны, но вот браузерные вычисления — не очень ¯⁠\⁠()⁠/⁠¯
  • если шрифт не загрузился, у резервного шрифта скорее всего другие метрики, а работать с несколькими разными значениями быстро станет практически нереально.

В сухом остатке

Что мы узнали:

  • понять строчный (инлайновый) контекст форматирования нелегко
  • у всех строчных элементов 2 высоты
    • область содержимого (основанная на метриках шрифта)
    • виртуальная область (line-height)
    • ни ту, ни другую высоту нельзя однозначно визуализировать (если вы разрабатываете браузерный отладчик и готовы взяться за это — было бы великолепно!)
  • line-height: normal основывается на метриках шрифта
  • при line-height: n виртуальная область может стать меньше, чем область содержимого
  • на vertical-align нельзя особо полагаться
  • высота контейнера строки рассчитывается на основе свойств line-height и vertical-align его потомков
  • нельзя просто взять и получить/установить метрики шрифта из CSS
  • есть в планах спецификация на эту тему, чтобы помочь с вертикальным выравниванием: модуль строчной сетки (Line Grid)

Но я по-прежнему люблю CSS :)

Полезные ссылки

  1. неважно, что вы выберете, здесь речь не об этом
  2. это не совсем так
  3. в других редакторах это может быть и расстояние между базовыми линиями. В Ворде, в Фотошопе это так. Главное отличие в том, что в CSS оно влияет и на первую строку
  4. можно использовать и переменные из препроцессоров, не в пользовательских свойствах суть

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

8 Комментарии

  1. faiwer

    Классная статья. Спасибо за перевод. Давно хотелось с этим разобраться.

  2. Алексей

    Элемент (черная рамка) состоит из контейнеров строк (белые рамки), состоящих из строчных элементов (сплошные рамки) и анонимных элементов строки (белые рамки)

    Видимо ошибка: и анонимных элементов строки (пунктирные рамки).

    1. SelenIT (Автор записи)

      Спасибо! Моя промашка(. Исправлено!

  3. Владимир

    Спасибо за статью, многое стало понятнее!

  4. Алексей

    По переводу: мне кажется в некоторых случаях переводите слишком буквально. По-русски фраза «В этом большая разница» будет звучать: «И в этом большая разница!» (хотя вообще, наверное, в зависимости от контекста). Аналогично, фраза «И в этом большая разница!» на английском будет переведена, вероятно, без And. И таких моментов может быть много (я не знаю, удачный ли я привёл пример). Пусть перевод будет чуть более вольный, но, при этом, не звучит нигде натянуто, если для смысла это не критично. Авторы привыкли говорить так, как принято там, где они общаются, но мысли их могут быть понятны и нам :-) Если типичные для слушателя обороты речи, смогут более естественно передать ОРИГИНАЛЬНОСТЬ АВТОРСКОЙ МЫСЛИ, то может лучше использовать их?
    Напоминаю, что высота контейнера строки рассчитывается от самой высокой до самой низкой точки его потомков.
    Тут ещё хорошо бы напомнить, что область содержимого находится ПОСЕРЕДИНЕ line-height. При первом прочтении это не очевидно :-)
    А вообще статья просто превосходна! Очень порадовала!..
    Странно, а почему Вы не даёте ссылку на свою книжку? Скромничаете?
    По-сути в этой статье разъяснены некоторые моменты, которые затрагиваются в Вашей книжке. Статья здорово её дополняет, развевает туман в некоторых местах, например вносит практически полную ясность в базовое понятие «высота строки», на котором многое строится и не понимая которое, очень сложно воспринять те или иные аспекты строчного форматирования и разобраться как же именно они работают…
    ЗЫ: По поводу рассчётов в CSS тоже тут недавно вёл рассчёты (в Маткаде), чтоб понять откуда-докуда заливать градиент у траснформируемой фигуры. Не то, что это плохо само по себе, но всё же, в некоторых аспектах, пожалуй, несколько запутанно. Думаю, что некоторые дополнительные возможности (не упрощения!) сделали бы реализацию тех или иных вполне интуитивных задач более простой и надёжной. Вот как раз:
    ЗЫЗЫ: Собираетесь ли Вы вносить в спецификацию, какие-то свои предложения, по строчному форматированию? :-)

    1. SelenIT (Автор записи)

      в некоторых случаях переводите слишком буквально

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

      ещё хорошо бы напомнить, что область содержимого находится ПОСЕРЕДИНЕ line-height.

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

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

      Именно поэтому я так спешил ее перевести:). Свежий взгляд на знакомую тему, причем за это время браузеры избавились от многих разночтений, более-менее удалось «разрулить» путаницу с переводом многозначных терминов типа «inline», и т.п.

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

      1. Алексей


        Слегка торопился успеть опубликовать перевод

        Да в целом-то нормально, я просто обратил внимание, что когда читаешь переводные статьи то иногда сталкиваешь с такой конструкцией фраз, что понимаешь, что автор — англоговорящий (в данном случае даже француз %)


        до намечавшегося на работе аврала

        Эх, где взять хвалёную в Вашей статье Путь верстальщика «программистскую мудрость», чтоб знать: когда капать, а когда не капать :-))


        Чтобы не пришлось в итоге перечислять всё, из чего складывается расстояние от базовой линии до нижнего края «виртуальной области»
        </cite

        Сложно сказать нужно это или нет, но могу сказать одно, когда разбираешься в чём-то сложном, мысленно раскладываешь его на (относительно) простые компоненты, о которых читал ранее… И тут иногда очень здорово проверить, что твои мысли сошлись с авторскими :-)
        Иначе потом совсем можно потеряться…

        «виртуальной области» (удачный авторский термин, кстати).
        Насколько мне известно, слово «виртуальный» в английском языке имеет немного более ёмкое значение чем в русском. Если в русском это что-то вроде «воображаемый», «не существующий» «предполагаемый в уме» ну в лучшем случае «где-то в параллельном мире», то в английском, это что-то вроде «непроявленное». То есть, в явном виде может и не существующее, но о чём-то говорящее… Вот и line-height, с одной стороны его увидеть не получается, но его параметры дают другим значениям найти своё конкретное и вполне законное место в строке.


        спасибо за замечание, возможно, кому-то этот комментарий поможет быстрее разобраться!

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


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

        Да, большая тема…
        Спасибо!

  5. Site

    Спасибо!

Добавить комментарий для faiwer Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

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