HTML in CSS: как сократить HTML-код и писать только на CSS
О проекте
Принцип DRY
Представьте: у вас есть страница с неким взаимосвязанным кодом. Если заменить одну строку в одном фрагменте, придется вносить изменения в зависимые блоки. А если вдруг забыли их поменять, то, скорее всего, вас будет ждать долгий поиск и мучительное решение проблемы.
Чтобы предотвратить ошибку, я решил придерживаться главной заповеди чистого кода — DRY, Don’t Repeat Yourself. Принцип помогает сократить повторяющийся код за счет разделения проекта на мелкие независимые модули. Туда можно с легкостью вносить новые изменения — другие блоки не пострадают.
DRY замотивировал меня разработать такой проект, в котором принцип осуществлялся на 110%. Изначально, чтобы сверстать страницу, нужно было описать структуру документа в HTML, а потом — в селекторах на CSS. Приходилось проделывать работу дважды.
Стало интересно, что будет, если поменять структуру документа. Перестать тратить время на написание кода в двух местах и сконцентрироваться только на CSS?
Работа с фреймворком
Кратко расскажу о принципе работы фреймворка. HTML in CSS — это способ избежать повторяющийся код. В нем можно писать только на CSS, HTML будет генерироваться самостоятельно.
Перед вами стандартная страница с версткой:
<head>
<style>
h1#title {
font-size: x-large;
margin-bottom: 32px;
}
main#main {
color: purple;
}
</style>
</head>
<body>
<h1 id="title">Заголовок</h1>
<main id="main">
Крутой контент
</main>
</body>
Синьоры и сеньориты среди вас, вероятно, заметили, что лишняя информация находится:
- в HTML —
h1 id="title"
; - в CSS —
h1#title {
; - в HTML —
main id="main"
; - в CSS —
main#main
.
HTML полностью повторяет код в CSS, поэтому я решил убрать содержимое тега <body>
. Без него мы не потеряем ничего, кроме контента:
<head>
<style>
h1#title {
font-size: x-large;
margin-bottom: 32px;
}
#title:before {
content: "Заголовок";
}
main#main {
color: purple;
}
#main:before {
content: "Крутой контент";
}
</style>
</head>
<body></body>
Особенности фреймворка
HTML in CSS можно использовать практически на любом коде сайта, но есть несколько оговорок.
Селекторы могут создать только один элемент и не более — двух одинаковых id не бывает.
#parent > #child {}
Текстовое содержание должно находиться в псевдоэлементах, иначе не получится передать внутреннее содержимое тега через CSS.
#kopyl-link::before {
content: "Ссылка на наш сайт";
}
Страница может запускаться только в рантайме, поэтому о SEO-оптимизации стоит забыть. Это норма для многих современных фреймворков, если не говорить об их SSR-вариациях.
Работа с элементами
О проекте и его особенностях мы узнали. Теперь рассмотрим, как использовать ссылки, вложенность, порядок и другие функции с помощью инструмента.
Ссылки
CSS код
a#kopyl-link[href="kopyl.dev"] {
display: block;
}
#kopyl-link::before {
content: "Ссылка на наш сайт";
}
Сгенерированный HTML
<a
id="kopyl-link"
href="kopyl.dev"
></a>
А если хотите, чтобы ссылка открывалась в новой вкладке?
CSS код
a#kopyl-link[href="kopyl.dev"][target="_blank"] {
display: block;
}
Сгенерированный HTML
<a
id="kopyl-link"
href="kopyl.dev"
target="_blank"
></a>
Вложенность
CSS код
#parent {
width: 200px;
height: 200px;
background-color: blue;
}
#parent > #child {
width: 100px;
height: 100px;
background-color: green;
}
Сгенерированный HTML
<div id="parent">
<div id="child"></div>
</div>
Порядок
Используя селекторы псевдоклассов :nth-child
, :first-child
, :last-child
, можно задать порядок элементов.
CSS код
#parent > #foo:last-child {
font-size: 10px;
}
#foo::before {
content: "Я последний";
}
#parent > #bar:first-child {
font-size: 20px;
}
#bar::before {
content: "А я первый";
}
Сгенерированный HTML
<div id="parent">
<div id="bar"></div>
<div id="foo"></div>
</div>
JavaScript
К сожалению, фреймворк не поддерживает JavaScript, но это не мешает подключить к нему внешний файл — main.js
. Да и никто не запретит нам описывать селекторы для тегов script
и добавлять туда атрибуты.
script#my-script[src="/main.js"] {}
В main.js
можно использовать любой интерактив, который нужен сайту, — например, обработку событий, клиентский роутер и другие.
Заключение
Возможно, некоторые уже захотели переписать свой продакшн-сайт на HTML in CSS, но мне жаль вас огорчать — на самом деле это фреймворк-шутка.
Одним вечером мне стало интересно, как парсится CSS и как выглядит его структура. В процессе изучения пришла в голову идея создать свой фреймворк. Занимает он, кстати, около 120 строк неубористого кода.
UPD: 02.10.2024
У проекта появился преемник в лице css2html.
Автор отнесся к идее несколько серьезнее и превратил проект во что-то, что можно и тайком юзнуть в SSR, вы, например, не можете быть уверенны, что эта страница не написана на css2html.
Подробности в статье автора проекта.