Создание каркаса сайта с помощью CSS and HTML5 [Перевод]

Создание каркаса сайта с помощью CSS and HTML5 [Перевод]

Статьи

Перевод статьи Эрика Мейера о создании каркасной модели сайта с помощью CSS and HTML5 — вот ссылка на оригинальный текст. Честно, я пока слабо представляю, как это можно использовать, но сама тема использования псевдо-элементов, градиентов и calc очень интересная. Сам Эрик Мейер предлагает использовать отображения каркасов во время разработки сайтов, чтобы показывать заказчикам, как продвигается работа над сайтом и из каких логических элементов состоит сайт.

Итак, слово Эрику Мейеру.

Недавно я познакомился с несколькими новыми идеями создания макетов на проекте Event Apart (например, Криса Койера или Джейн Симмонс) и хотел поделиться их идеями со своими друзьями. То, о чём мне действительно хочется рассказать — это создание каркасной модели сайта, чтобы показать базовую компоновку элементов сайта, его черновой вариант без «шлифовки» его деталей.

Я размышлял о том, чтобы сделать скриншоты страниц, а потом прифотошопить отображение каркасов элементов поверх изображения, но потом задумался над вопросом — могу ли сделать всё то же самое с помощью CSS на «живой» странице? Или даже это получится сделать это таким способом, чтобы не использовать ничего другого, кроме деклараций или бессмысленного пренебрежения чувствами бога или человека?

И тогда я понял … что могу. Теперь я собираюсь поделиться с вами своим открытием.

Прежде чем я начну, необходимо внести прояснить один момент — здесь нет места для обратной совместимости. Мне все равно. Этого не должно быть. Он работает в последних версиях Firefox и Chrome с разумными допусками — в Chrome есть небольшой момент, но про него расскажу, как только мы доберёмся до места.

Все хорошо? Тогда вперед.

Моя цель заключалась в создании каркаса их коробок с перекрестными линиями, которые так сильно любят каркасники (в оригинале «wireframers»). Я полагал, что любой элемент контейнера, который нужно отобразить в каркасной модели, получает class= «wireframe».

<div class="wireframe">…(здесь какой-то контент)…</div>

Не надейтесь использовать этот класс — он не доживёт до конца этой статьи. Это был спойлер!

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

Размер элементов со всеми дополнительными параметрами указывается с помощью свойства box-sizing. Но вы знаете — вы это делаете.

.wireframe {outline: 2px solid gray;}
Добавление простого каркаса (на локальной копии страницы Рейчел Эндрю)

Контуры каркасов накладываются друг на друга, поскольку элементы макета, во всяком случае, в правой части, находятся в плавающем режиме. Они расположены таким образом, что если контент в правой части небольшой, а биография автора и статьи имеют большую ширину, то они могут обернуться вокруг «сайдбара». Обычно полезно иметь возможность видеть контуры, показывающие фактические размеры элементов, к которым они прикреплены.

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

Рисование прямоугольного каркаса- это самая лёгкая часть. Теперь же нам нужны две диагональные линии, идущие из угла в угол. Но как их сделать?

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

Это именно то, что мне нужно! Итак:

.wireframe {
   outline: 2px solid gray;
   background:
      linear-gradient(to top right,
         transparent 49.9%, gray 49.9%,
         gray 50.1%, transparent 50.1%);
}

Отлично, у нас теперь есть одна диагональная линия. Вторая является копией первого, за исключением того, что он идет в сторону другого квадранта.

.wireframe {
   outline: 2px solid gray;
   background:
      linear-gradient(to top right,
         transparent 49.9%, gray 49.9%,
         gray 50.1%, transparent 50.1%),
      linear-gradient(to bottom right,
         transparent 49.9%, gray 49.9%,
         gray 50.1%, transparent 50.1%);
}
Диагональные линии!

Бинго: у нас появились X. Но не такие, как нам нужны — с масштабированием возникают определённые проблемы. Использование процентов означает, что серые линии будут толщиной 0,2% от общей длины градиентного луча. Если каркасный блок очень маленький, то и сами диагональные линии истончаются насколько, что становятся невидимыми, иногда ломаются диагонали. А у больших элементов и диагонали получаются более толстыми, чем у меньших собратьев.

Так что я исправил это с помощью Calc().

.wireframe {
   outline: 2px solid gray;
   background:
      linear-gradient(to top right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px)),
      linear-gradient(to bottom right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px));
}
Правильно определенные размеры диагональных линий готовы!

Вот то, что нам нужно — все диагональные линии два пикселя толщиной.

Здесь нужно отметить две вещи, прежде чем мы продолжим. Во-первых, добавление пространства вокруг операторов в значениях calc() сделано умышленно и, более того, необходимо для работы. Если удалить одно или оба этих пробела, calc() просто не будет работать. Другими словами, просто использоватьс calc (50% — 1px) не получится — нет для этого фона. Это так задумано разработчиками и на это есть свои причины (этот вопрос мы не будем рассматривать), достаточно лишь сказать, что это существует, и возможно, такое решение разумно. С другой стороны, сalc (50% — 1px) работает по назначению.

Ну или почти совсем: в Chrome отображение происходит немного по-другому. У больших элементов Chrome создаст нечёткие линии толщиной более 2 пикселей. Здесь происходит непонятное с указанными цифрами, связанное с восприятием движком браузера написанного кода. И линии здесь не проходят из угла в угол, как они должны. А вот на Firefox с линиями полный порядок, несмотря на то, какой будет размер элемента — это я проверил. Просто знайте о том, что в этом моменте Chrome проявляет себя неряшливо.

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

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

.wireframe {
   outline: 2px solid gray;
   position: relative; z-index: 1;
}
.wireframe::before {
   position: absolute;
   z-index: 8675309;
   top: 0; bottom: 0; right: 0; left: 0;
   background:
      linear-gradient(to top right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px)),
      linear-gradient(to bottom right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px)),
      #FFF9;
      content: "";
}
Размещение диагоналей и создание полупрозрачности над элементами

Я использовал ::before, главным образом потому, что «Ей, почему бы и нет?!», но также потому, что для clearfix обычно используется ::after, и я слышал, что люди все еще используют clearfix, что очень грустно. Таким образом, мы избежим использование этого псевдо-элемента. А если вы уже вы перешагнули через использование clearfix, то можете использовать::after также легко, как и::before. Как подскажет вам ваша фантазия. (Clearfix? Float? Ах, я убью себя!).

В псевдо-элементе у свойства z-index огромное значение поставлено от потолка и сделано для того, чтобы он гарантированно находился на слой выше любого элемента, который теоретически может находится на странице — с этой точки зрения, такой подход в выборе значения разумен. Вы можете поставить такое значение, которое вам понравится (и какое поддерживает ваш браузер). С другой стороны, маленькие значения z-index’а гарантирует, что они получают явное размещение стеков вместо автоматически назначенного места на оси Z. По моим наблюдениям, такой подход решает ряд странных поведений в различных браузерах. Ваш опыт может отличаться.

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

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

Что ж, мы уже имеем свойство содержимого, которое уже давно сидит и ждёт момента, когда мы им воспользуемся и заполним пустое значение свойства content в псевдо-элементе на соответствующее блоку содержание, но как это сделать? И в этот момент я понял, что время класса .wireframe подошло к концу.

Всё потому, что нет ничего проще, чем использовать для маркировки элементов атрибуты данных HTML, которые и будут помогать вывести на нашу каркасную модель соответствующий ярлык. А если там будет необходимый нам атрибут, тогда можно выводить стили каркаса над блоком просто исходя из наличия такого атрибута над блоком, а не используя лишние классы для отметки нужных элементов, которые, кроме всего, могут помешать некоторому неожиданному сценарию DOM? Поэтому я изменил разметку и CSS следующим образом:

<div data-wf="Articles">…(content goes here)…</div>
[data-wf] {
   outline: 2px solid gray;
   position: relative; z-index: 1;
}
[data-wf]::before {
   position: absolute;
   z-index: 8675309;
   top: 0; bottom: 0; right: 0; left: 0;
   background:
      linear-gradient(to top right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px)),
      linear-gradient(to bottom right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px)),
      #FFF9;
      content: "";
}

Серьезно, я едва не назвал этот атрибут data-wtf.

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

[data-wf] {
   outline: 2px solid gray;
   position: relative;
   z-index: 1;
}
[data-wf]::before {
   position: absolute;
   z-index: 8675309;
   top: 0; bottom: 0; right: 0; left: 0;
   background:
      linear-gradient(to top right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px)),
      linear-gradient(to bottom right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px)),
      #FFF9;

   content: attr(data-wf);
   font: bold 2em Jubilat, Georgia, serif;
   color: gray;
   display: flex;
   justify-content: center;
   align-items: center;
}
Добавление ярлыков-меток по центру

Эти стили придали нашему каркасу большие и заметные ярлыки-заголовки Jubilat (Jubilat — это один из брендовых шрифтов AEA), которые расположены прямо посередине каркаса, а диагональные линии проходят позади текста.

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

[data-wf] {
   outline: 2px solid gray;
   position: relative;
   z-index: 1;
}
[data-wf]::before {
   position: absolute;
   z-index: 8675309;
   top: 0; bottom: 0; right: 0; left: 0;
   background:
      linear-gradient(to top right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px)),
      linear-gradient(to bottom right,
         transparent calc(50% - 1px), gray calc(50% - 1px),
         gray calc(50% + 1px), transparent calc(50% + 1px)),
      #FFF9;

   content: attr(data-wf);
   font: bold 2em Jubilat, Georgia, serif;
   color: gray;
   text-shadow:
      0 0 0.25em #FFF9, 0 0 0.25em #FFF9,
      0 0 0.25em #FFF9, 0 0 0.25em #FFF9,
      0 0 0.25em #FFF9;
   display: flex;
   justify-content: center;
   align-items: center;
}
Создаём «сглаживание» для ярлыков элементов каркаса

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

Когда я посмотрел на результат, мне стало ясно, что используемая цветовая схема «белый+серый» неплохо работает для установки простого каркаса без брендинга, но мне хочется сделать такими, чтобы можно было использовать на разных дизайнах с применением используемых на текущей странице цветов и прочих штук, вот так вот. Мне не хочется, чтобы каркасный блок использовал полупрозрачный белый, а чтобы этот цвет был полупрозрачной версией фонового цвета страницы. И более того — я хочу иметь возможность легко изменить этот цвет при нанесении каркаса на различные элементы.

Пользовательские свойства да придут на помощь! Вернее, встроенные переменные CSS спасут нас!

Данная страница An Event Apart имеет фоновый цвет #F7F6F1 — код цвета, которую нужно запомнить на этом этапе. Поскольку я хотел сделать заливку непрозрачной на три четверти, то я устанавливаю цвет как #F7F6F1BB (BB указывают на 75% непрозрачности, если вдруг не знаете). В коде CSS определяем это свойство:

html {
   --fill: #F7F6F1BB;
}

Я мог бы назначить переменную для правила [data-WF] вместо html, но мне хотелось сделать эту настройку глобальной. Давайте также определим общую переменную для цвета контуров, диагоналей и текста ярлыков.

html {
   --fill: #F7F6F1BB;
   --wire: gray;
}

Теперь мне нужно отметить все места для вызовов переменных этих цветов. Я отмечаю их в следующих строчках:

html {
   --fill: #F7F6F1BB;
   --wire: gray;
}
[data-wf] {
   outline: 2px solid var(--wire);
   position: relative;
   z-index: 1;
}
[data-wf]::before {
   position: absolute;
   z-index: 8675309;
   top: 0; bottom: 0; right: 0; left: 0;
   background:
      linear-gradient(to top right,
         transparent calc(50% - 1px), var(--wire) calc(50% - 1px),
         var(--wire) calc(50% + 1px), transparent calc(50% + 1px)),
      linear-gradient(to bottom right,
         transparent calc(50% - 1px), var(--wire) calc(50% - 1px),
         var(--wire) calc(50% + 1px), transparent calc(50% + 1px)),
      var(--fill);

   content: attr(data-wf);
   font: bold 2em Jubilat, Georgia, serif;
   color: var(--wire);
   text-shadow:
      0 0 0.25em var(--fill), 0 0 0.25em var(--fill),
      0 0 0.25em var(--fill), 0 0 0.25em var(--fill),
      0 0 0.25em var(--fill);
   display: flex;
   justify-content: center;
   align-items: center;
}
Конечный продукт, с цветными темами и всем необходимым

В принципе, ярлыки можно также выделить с помощью использования его собственной переменной (например, —text или —label) достаточно легко, но в данном варианте мне нет необходимости такой тонкой настройки цветов — всё по-минимуму. Я слишком хорошо знаю себя в желании настроить кучу элементов управления, чтобы играть параметрами, особенно когда речь идет о цвете.

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

Теперь, когда мы подошли к концу. Надеюсь, вам понравилось наше небольшое путешествие по различным местам в CSS. Если у вас появились вопросы, не стесняйтесь, напишите их в комментариях ниже (оставьте комментарий для Эрика на его сайте). Я сделаю все возможное, чтобы ответить в разумные сроки.

P.S.: И последнее замечание, как сказал бы в этом случае Кай Риссдал: каждый бит CSS, который я использовал здесь, описан в CSS: The Definitive Guide, 4th Edition. Я дважды обращался к своей печатной книге в процессе разработки этого каркаса, для того, чтобы напомнить себе определенный синтаксис (для пользовательских свойств) и требования к пробелам для оператора Calc(). И это реально приятно, когда то, что я сделал, оказалось полезным для меня.

Анатолий Куликов

Анатолий Куликов

Автор блога, веб-разработчик
  • at sign
  • vk logo
Комментариев нет

Добавить комментарий

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