DRY-фреймворк: продолжение

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Особая благодарность автору идеи @akopyl Его статья по теме.

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

Изначально идея имела реализации: раз, и даже две, но:

  1. Одна (а то и обе, ибо ссылаются на API document), насколько я понял, работают исключительно в рамках веб‑страницы, то есть, не могут быть использованы, как самодостаточные библиотеки.

  2. Криво реализуют текст в тегах — либо через псевдо‑элементы (sic!), либо через свойство content, что уже лучше, но не совсем валидно (теоретически, может произойти коллизия, по этой логике добавляли data-* атрибуты для HTML).

  3. Писать атрибуты для элементов — сущий ад, ибо делается это только через селектор.

Автором статьи преследовалась цель создать улучшенный вариант библиотеки, которая работает вне рамок веб‑страницы (как отдельная библиотека), имеет усовершенствованные механизмы добавления тегов, текста… И по мелочи.

Что это и где достать

Проект на npm и GitHub.
Суть библиотеки в том, чтобы конвертировать это:

section#some-id {
  --text: 'Это текст, товарищ!';
  --attr-title: 'Заголовок';
  background: red;
  color: aliceblue;
}
section#some-id header[data-attribute='v'] {
  --text: 'Это текст шапки';
  color: blue;
}
section#some-id span {
  --text: 'Это внутренний текст';
  --text-after: 'А это текст после';
  color: peru;
}

В это:

<section id="some-id" title="Заголовок">
  Это текст, товарищ!
  <header data-attribute="v">Это текст шапки</header>
  <span> Это внутренний текст </span>А это текст после
</section>

Далее — принцип работы библиотеки невкратце.

Элементы

Создать элемент можно через селектор:

div.classname#id[attr-1][attr-2='v'] {
  /* Ни одна из частей селектора обязательной не является */
  /* Но хоть что-то нужно оставить */
}

div {}
div span {
  /* Поддерживается вложенность */
}
<div id="id" class="classname" attr-1 attr-2="v"></div>

<div>
  <span></span>
</div>

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

  • Псевдо‑класс

  • Псевдо‑элемент

  • Один из этих селекторов: *, +, >, ||, |, ~

  • Или оберните в @at-rule

Пример — эти селекторы будут проигнорированы:

> div.classname#id[attr-1][attr-2='v'] {
}
div span * {
}
div::before {
  /* Да, и этот тоже */
}
div:not(:has(span)) {
  /* И этот тоже! */
}
@container (width > 1440px) {
  span[data-a='Этот элемент будет проигнорирован тоже'] {}
}

Текст и атрибуты

Атрибуты можно задать через селектор (бывает полезно при стилизации), а можно через кастомные свойства --attr-* и --attrs

/* В селекторе */
a[title='Title!']{
  
  /* Точечно (внимание на то, что после attr-) */
  --attr-href:'./index.html';
  
  /* И массово! */
  --attrs:'target="_self" rel="noopener noreferrer"';
}
<a title="Title!"
   href="./index.html"
   target="_self"
   rel="noopener noreferrer"
></a>

Вписать текст в элемент не проблема - через специальное кастомное свойство:

div {
  --text: 'И вновь продолжается бой';
}
<div> И вновь продолжается бой </div>

Если нужно вставить тег посреди текста, придётся немного вывернуться.
Технически, можно просто вписать тег в переменную текста:

div { --text: 'Никогда <span>не</span> делайте так!'; }

Но, как и указано, лучше так не делать.
Для этого есть специальные кастомные свойства, позволяющие вписать текст до и после тега:

div {
  --text: 'Текст внутри div';
}
div span {
  --text: 'Это текст внутри';
  --text-before: '| до тега';
  --text-after: '| после тега';
}
<div>
  Текст внутри div | до тега<span> Это текст внутри </span>| после тега
</div>

API

Так‑с, с возможностями понятно, теперь об API.
Самый минимум для запуска выглядит так:

import { CssToHtml } from 'css2html'

let result = new CssToHtml({ css: "div{}", })
console.log(result.outputHTML)

Этот код выводит в терминал/консоль результат обработки простейшего CSS из одного тега.
Но это, конечно, не всё, это же минимум.

Для записи html непосредственно в файл, добавьте параметр write
(Внимание! Весь файл будет перезаписан)

new CssToHtml({
 ...,
  write: {
    in: "Ваш_путь_к_html_файлу",
  },
})

Однако, есть один нюанс. Дело в том, что html имеет некоторый функционал, который через css передать так трудно, что лучше не пытаться. Например — скрипты написанные прямо в HTML или карты импорта.

А по умолчанию файл перезаписывается полностью, что ведёт к утрате бесценного кода, который не описать нормально в рамках css. В таких случаях нужно указывать конкретно, куда писать, вместо перезаписи всего.
С помощью параметров after и before как раз это и можно сделать — указывается область, которая будет доступна для перезаписи.

new CssToHtml({
  ...,
  write: {
    in: "Ваш_путь_к_html_файлу",
    after: "<body>",
    before: "</body>",
  },
})

А ещё, HTML который создаёт библиотека кое‑как форматируется. За это отвечает плагин js‑beatify, которому можно передать параметры:

new CssToHtml({
  ...,
  formatterOptions: {
    indent_size: 2,
  },
})

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

Нечто большее

Попытки объединить разметку, стилизацию и даже скрипты предпринимались неоднократно. JSX, описание стилей через JS‑объект, даже Tailwind по сути занимается встраиванием стилей в HTML, брр…
Tailwind достоин отдельных тёплых слов, а по поводу остальных — попытки достойные, но результат недостаточный — они не объединяют. Они, грубо говоря, позволяют написать всё «в одну кучу» за счёт разбиения на зоны того или иного языка внутри одного файла. Это как взять кирпичи, бетон, стекло и пытаться сделать из них цельную стену.

Эта библиотека— попытка свести к минимуму или вовсе отказаться от одного из инструментов фронт‑энд разработки — HTML, перенеся его функции на другой инструмент — CSS. Можно пойти ещё дальше (за пределами этой библиотеки, естественно), соединив функции разметки, стилизации и скриптов — получился бы этакий единый язык веб‑страниц (название временное, придумано на "ход"у).

Очень большой соблазн повторить JSX — он кажется подходящим, но нет. Помимо причин, описанных выше, он слишком «жёсткий» для стилизации (либо через строки, либо через объекты, где селекторы в кавычках — отдельный «шедевр»), а попытки впилить в него ещё и CSS в чистом виде сделают его ещё больше походящим на кучу стройматериала.

Как и автор идеи этой библиотеки, я приведу свои мысли. На этот раз — по поводу языка, которого ещё нет.

  • Менять интернет из‑за нового языка никто не будет, ломать совместимость — последнее дело для таких больших структур. Лучше всего делать язык как препроцессор.

  • Язык должен одновременно описывать стили, разметку и логику используя одну лексику и грамматику, без разбиения на «диалекты».

  • Стоит вдохновиться чем-нибудь вроде 11l. Честно, C‑образные языки уже достали, да и громоздкие они для таких задач. Желательно без однобуквенных операторов.

Сейчас мне на такую задачу не хватит времени. Посмотрим, хватит ли у кого смелости, желания и умения.

Источник: https://habr.com/ru/articles/847542/


Интересные статьи

Интересные статьи

Привет! Вероятно, тебе когда-нибудь попадались веб-приложения, построенные на «1С-Битрикс: Управление сайтом», и ты задавался вопросом: как это ломать? Вроде бы прошелся по всем известной методичке, н...
Битрикс24 — корпоративное SaaS-решение (Software as a Service, программное обеспечение как услуга), которым пользуются компании разного масштаба и профиля для коммуникации между сотрудниками, хран...
Привет, Хабр!В одной из предыдущих статей блога ISPsystem уже упоминался тот факт, что после февральских событий этого года на волне активного импортозамещения количество запросов на наши продукты выр...
Их было шестеро - барабанщик, басист, клавишник, гитарист, баянист и человек с татуировками. Как-то так начинался бы фильм о нас, о музыкальной группе Sun-Techniki.Вы, во...
Я давно знаком с Битрикс24, ещё дольше с 1С-Битрикс и, конечно же, неоднократно имел дела с интернет-магазинами которые работают на нём. Да, конечно это дорого, долго, местами неуклюже...