mod: front (6) сборка TialWindCSS и кастомыне base и слои
This commit is contained in:
@@ -27,22 +27,44 @@
|
|||||||
{# Шутка #}<meta name="generator" content="Microsoft FrontPage 1.0"/>
|
{# Шутка #}<meta name="generator" content="Microsoft FrontPage 1.0"/>
|
||||||
<link rel="icon" type="image/svg+xml" href="{% static 'svgs/favicon.svg' %}" />
|
<link rel="icon" type="image/svg+xml" href="{% static 'svgs/favicon.svg' %}" />
|
||||||
<link rel="icon" type="image/png" href="{% static 'img/favicon.png' %}" />
|
<link rel="icon" type="image/png" href="{% static 'img/favicon.png' %}" />
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="{% static 'img/favicon.ico' %}" />{% comment %}
|
<link rel="shortcut icon" type="image/x-icon" href="{% static 'img/favicon.ico' %}" />
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
{% if IS_DEBUG %}{% comment %}
|
||||||
ВАЖНО! В prod будет использоваться tailwind.min.css. Его собирет webpack специально под проект.
|
Переключение dev/prod стилей Tailwind CSS происходит АВТОМАТИЧЕСКИ через
|
||||||
Для этого у него в input.css прописаны пути к шаблонам, на которые ему надо посмостеть, и он соберет только
|
переменную IS_DEBUG (см. контексный-процессор frontend/context_processors.py),
|
||||||
используемые классы и сгенерирует уникальный tailwind.min.css проекта.
|
|
||||||
<link rel="stylesheet" href="{% static 'css/tailwind.min.css' %}">{# <-- ДОБАВИТЬ В ПРОДАКШЕНЕ #}
|
|
||||||
|
|
||||||
В dev используем tailwindcss из CDN. В нем есть все, но он неимоверно грузит браузер.{% endcomment %}
|
DEV: tailwindcss из CDN, компилируется прямо в браузере. Удобно для
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>{# <-- УБРАТЬ В ПРОДАКШЕНЕ #}
|
разработки (не нужна сборка), но грузит браузер и prod не используется.
|
||||||
|
{% endcomment %}<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>{% comment %}
|
||||||
|
|
||||||
|
Кастомные @theme/@layer директивы проекта (токены цвета, типовой стиль
|
||||||
|
ссылок) лежат в css/tailwind-custom.css. @tailwindcss/browser сканирует
|
||||||
|
и компилирует ТОЛЬКО то, что видит в финальном DOM — то есть только
|
||||||
|
содержимое тегов style с type text/tailwindcss, а не внешние .css,
|
||||||
|
подключённые через link. Поэтому файл вставляется сюда через include,
|
||||||
|
а не подключается отдельным link.
|
||||||
|
|
||||||
|
Строка "@import tailwindcss" ниже ОБЯЗАТЕЛЬНА (проверено на практике):
|
||||||
|
без неё @apply в css/tailwind-custom.css не может найти стандартные
|
||||||
|
классы Tailwind (border-slate-500 и т.п.), браузерный компилятор
|
||||||
|
падает с ошибкой уже на этапе разбора — и из-за этого перестаёт
|
||||||
|
генерироваться ВООБЩЕ ВСЯ Tailwind-разметка на странице (не только
|
||||||
|
кастомные стили), верстка превращается в неоформленный HTML.{% endcomment %}
|
||||||
|
<style type="text/tailwindcss">
|
||||||
|
@import "tailwindcss";
|
||||||
|
{% include "css/tailwind-custom.css" %}
|
||||||
|
</style>{% else %}{% comment %}
|
||||||
|
PROD: заранее собранный Tailwind CLI файл (см. frontend-assembly/tailwind/input.css
|
||||||
|
и package.json). CLI сканирует шаблоны проекта и генерирует только реально
|
||||||
|
используемые классы, включая кастомные @theme/@layer директивы из того же
|
||||||
|
самого файла css/tailwind-custom.css (подключён в input.css через @import).{% endcomment %}
|
||||||
|
<link rel="stylesheet" href="{% static 'css/tailwind.min.css' %}">{% endif %}
|
||||||
<script type="application/ld+json">
|
<script type="application/ld+json">
|
||||||
{
|
{
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "WebSite",
|
"@type": "WebSite",
|
||||||
"name": "LPON.RU",
|
"name": "LPON.RU",
|
||||||
"url": "{{ request.scheme }}://{{ request.get_host }}/"
|
"url": "{{ request.scheme }}://{{ request.get_host }}/"
|
||||||
}
|
}
|
||||||
</script>{% block EXTRAHEAD %}{% endblock EXTRAHEAD %}
|
</script>{% block EXTRAHEAD %}{% endblock EXTRAHEAD %}
|
||||||
<link rel="stylesheet" href="{% static 'css/lpon.css' %}" />
|
<link rel="stylesheet" href="{% static 'css/lpon.css' %}" />
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
tailwind-custom.css — кастомные Tailwind-директивы проекта lpon.ru
|
||||||
|
(c) 2026, Sergei Erjemin, https://lpon.ru
|
||||||
|
{% comment %}
|
||||||
|
ВНИМАНИЕ: этот файл не просто CSS! Это Django-шаблон, который подключается через
|
||||||
|
include-тег в инлайновый блок <style type="text/tailwindcss"> шаблона _base.html.
|
||||||
|
|
||||||
|
ВАЖНО: этот файл содержит ТОЛЬКО директивы @theme/@layer, которые обязаны
|
||||||
|
пройти через компилятор Tailwind, поэтому подключать его напрямую через
|
||||||
|
<link rel="stylesheet"> НЕЛЬЗЯ — обычный браузерный CSS-парсер не понимает
|
||||||
|
@theme/@apply и просто отбросит эти правила (проверено на практике: именно
|
||||||
|
так "молчал" прежний lpon.css).
|
||||||
|
|
||||||
|
ОЧЕНЬ ВАЖНО: Так как этот CSS-файл сам является Django-шаблоном (подключается
|
||||||
|
инлайн через include-тег движка шаблонов), то внутри него НЕЛЬЗЯ писать буквенные
|
||||||
|
примеры Django-тегов вида "открыть-процент include ... процент-закрыть" —
|
||||||
|
движок шаблонов исполнит их по-настоящему, даже внутри CSS-комментария.
|
||||||
|
Это может привести к бесконечным рекурсиям (файл случайно подключал
|
||||||
|
сам себя) и другим непредсказуемым последствиям.
|
||||||
|
Если использовать комментарии для шаблонов Django, как здесь, то это безопасно.
|
||||||
|
|
||||||
|
Файл используется в ДВУХ местах одновременно:
|
||||||
|
1. В dev — подключается инклюд-тегом движка шаблонов Django ВНУТРИ
|
||||||
|
инлайнового блока <style type="text/tailwindcss"> в _base.html.
|
||||||
|
Именно этот блок сканирует и компилирует CDN-скрипт
|
||||||
|
@tailwindcss/browser прямо в браузере (он видит только финальный DOM,
|
||||||
|
а не внешние .css-файлы, подключённые через <link>).
|
||||||
|
2. В prod — подключается через нативный CSS @import из
|
||||||
|
frontend-assembly/tailwind/input.css в сборщике scripts/build-tailwind.sh.
|
||||||
|
Результат Tailwind CLI собирает в public/static/css/tailwind.min.css
|
||||||
|
(см. frontend-assembly/tailwind/package.json).
|
||||||
|
|
||||||
|
Поэтому здесь НЕТ строки `@import "tailwindcss";` — её добавляет каждый
|
||||||
|
"потребитель" данного файла САМ, непосредственно перед подключением этого
|
||||||
|
файла: инлайновый блок в _base.html (в dev) и input.css (в prod). Без
|
||||||
|
этого импорта директива @apply внутри @layer base ниже не сможет найти
|
||||||
|
используемые в ней стандартные классы (border-slate-500 и т.п.) и упадёт
|
||||||
|
с ошибкой "Cannot apply unknown utility class" — при этом в dev это ломает
|
||||||
|
ВООБЩЕ ВСЮ генерацию Tailwind CSS на странице (проверено на практике).
|
||||||
|
{% endcomment %} */
|
||||||
|
@theme { /* -- Кастомные переменные цветов -- {% comment %}
|
||||||
|
@theme задаёт кастомные токены цвета, которые можно использовать
|
||||||
|
в Tailwind-классах через синтаксис, например, text-(--color-link)
|
||||||
|
Это позволяет менять стили глобально, не бегая по шаблонам и не меняя конкретные
|
||||||
|
классы, а просто перекрашивая токены цвета в одном месте. {% endcomment %} */
|
||||||
|
--color-link: var(--color-slate-500);
|
||||||
|
--color-link-hover: var(--color-indigo-800);
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base { /* -- СЛОЙ BASE для Tailwind v4.0+ — см. https://tailwindcss.com/docs/layer-directive --{% comment %}
|
||||||
|
Типовой стиль ссылки "по умолчанию" для всего проекта.
|
||||||
|
|
||||||
|
Поэтому обычную текстовую ссылку теперь можно писать в шаблоне вообще без
|
||||||
|
class="..." (просто тег a с href и текстом внутри, без единого класса) —
|
||||||
|
и она сразу получит фирменный вид сайта (пунктирное подчёркивание,
|
||||||
|
типовой цвет и ховер). Именно так сделано в block/breadcrumbs.html.
|
||||||
|
|
||||||
|
ВАЖНЫЙ НЮАНС для ссылок, которые НЕ должны выглядеть как "типовая
|
||||||
|
текстовая ссылка" (например, пункты меню-кнопок в block/header.html —
|
||||||
|
там ссылка визуально оформлена как кнопка, а не как подчёркнутый текст):
|
||||||
|
Tailwind v4 использует настоящие CSS cascade layers (@layer base,
|
||||||
|
components, utilities...), и по их правилам слой `utilities` ВСЕГДА
|
||||||
|
побеждает слой `base` независимо от специфичности селектора — НО только
|
||||||
|
для тех CSS-свойств, которые реально заданы в utilities-классе на этом
|
||||||
|
элементе. Если у пункта меню нет своего класса для color/border (как
|
||||||
|
сейчас в header.html — там заданы только фон и отступы через
|
||||||
|
hover:bg-gray-200, px-4 и т.п.), то свойства color/border-bottom он
|
||||||
|
"унаследует" именно отсюда, а не из своего блочного оформления —
|
||||||
|
родительский text-slate-900 на <menu> тут не поможет, т.к. у самого
|
||||||
|
<a> появится СВОЙ явный color.
|
||||||
|
Поэтому такие ссылки-кнопки должны явно "отключать" типовой стиль:
|
||||||
|
добавить border-0 (убирает пунктир) и свой text-slate-900 dark:text-
|
||||||
|
slate-100 (задаёт свой цвет вместо цвета типовой ссылки) — это и сделано
|
||||||
|
в block/header.html.{% endcomment %} */
|
||||||
|
a {
|
||||||
|
@apply border-b border-dotted border-slate-500 dark:border-slate-300
|
||||||
|
text-(--color-link) dark:text-slate-300
|
||||||
|
hover:text-(--color-link-hover) dark:hover:text-indigo-200
|
||||||
|
hover:border-solid transition-colors;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
lpon.css — обычный (не Tailwind-специфичный) CSS сайта lpon.ru
|
||||||
|
(c) 2026, Sergei Erjemin, https://lpon.ru
|
||||||
|
|
||||||
|
ВАЖНО: этот файл подключается напрямую через <link rel="stylesheet">
|
||||||
|
и НЕ проходит через компилятор Tailwind.
|
||||||
|
Tailwind-директивы (@theme, @layer, @apply) здесь работать НЕ БУДУТ!
|
||||||
|
|
||||||
|
Сейчас таких стилей нет, файл пуст.
|
||||||
|
*/
|
||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -17,6 +17,15 @@ fail() {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Скрипт идемпотентный и не оставляет после себя рабочих файлов: input.css
|
||||||
|
# генерируется заново при каждом запуске (см. ниже), а node_modules ставится
|
||||||
|
# через `npm ci` (чистая установка по package-lock.json). Поэтому ни один из
|
||||||
|
# этих файлов не хранится в репозитории и не добавлен в .gitignore отдельно -
|
||||||
|
# cleanup() гарантированно подчищает их за собой при любом завершении скрипта
|
||||||
|
# (успех, ошибка, Ctrl+C). Единственное исключение - если процесс убьют
|
||||||
|
# принудительно (kill -9/SIGKILL), тогда trap не сработает и файлы останутся
|
||||||
|
# на диске; в этом случае их можно смело удалить руками либо просто повторно
|
||||||
|
# запустить скрипт - он всё перезапишет.
|
||||||
cleanup() {
|
cleanup() {
|
||||||
rm -rf "$TAILWIND_DIR/src" "$TAILWIND_DIR/node_modules" "$TAILWIND_DIR/tailwind.config.js" "$TAILWIND_DIR/input.css"
|
rm -rf "$TAILWIND_DIR/src" "$TAILWIND_DIR/node_modules" "$TAILWIND_DIR/tailwind.config.js" "$TAILWIND_DIR/input.css"
|
||||||
}
|
}
|
||||||
@@ -39,17 +48,42 @@ mkdir -p "$OUTPUT_DIR"
|
|||||||
|
|
||||||
log "Создаю entry point для Tailwind"
|
log "Создаю entry point для Tailwind"
|
||||||
|
|
||||||
# input.css (entry point)
|
# input.css (entry point для Tailwind CLI).
|
||||||
# Проверяем: если input.css вообще нет, только тогда создаем базовый
|
# ВАЖНО: этот файл перезаписывается безусловно при КАЖДОМ запуске скрипта
|
||||||
|
# (не только если его нет) - он одноразовый, генерируется прямо здесь
|
||||||
|
# через heredoc и удаляется в конце работы скрипта через cleanup()
|
||||||
|
# (см. начало файла). Поэтому input.css не хранится в репозитории и
|
||||||
|
# его не нужно редактировать руками - любые правки нужно вносить
|
||||||
|
# в текст heredoc ниже, иначе они потеряются при следующей сборке.
|
||||||
# ВАЖНО: Tailwind так устроен, что он собирает в CSS только те классы, которые реально используются в исходниках (HTML,
|
# ВАЖНО: Tailwind так устроен, что он собирает в CSS только те классы, которые реально используются в исходниках (HTML,
|
||||||
# Python и т.д.) Это очень круто, т.к. финальный CSS проекта будет минимальным по размеру!
|
# Python и т.д.) Это очень круто, т.к. финальный CSS проекта будет минимальным по размеру!
|
||||||
# Чтобы Tailwind знал, где искать классы, нужно указать ему исходники через директиву @source в input.css.
|
# Чтобы Tailwind знал, где искать классы, нужно указать ему исходники через директиву @source в input.css
|
||||||
# @source "../../lpon_site/templates/**/*.html"; <-- ищем все HTML-шаблоны в проекте
|
# (см. подробный комментарий прямо над самими директивами @source внутри heredoc ниже).
|
||||||
# @source "../../lpon_site/frontend/**/*.py"; <-- ищем все Python-файлы в проекте (например, там могут
|
|
||||||
# генерироваться классы, которые генерируют HTML)
|
|
||||||
cat > "$TAILWIND_DIR/input.css" <<'EOF'
|
cat > "$TAILWIND_DIR/input.css" <<'EOF'
|
||||||
@import "tailwindcss";
|
/*
|
||||||
|
input.css — точка входа для сборки prod-версии Tailwind CSS (Tailwind CLI).
|
||||||
|
|
||||||
|
Собирается командой `npm run build` (см. package.json в этой же папке) в
|
||||||
|
файл public/static/css/tailwind.min.css, который подключается в _base.html
|
||||||
|
для production (когда settings.DEBUG == False).
|
||||||
|
|
||||||
|
Здесь же подключаются кастомные @theme/@layer директивы проекта из общего
|
||||||
|
файла lpon_site/templates/css/tailwind-custom.css — того же самого файла,
|
||||||
|
который в dev-режиме подключается через {% include %} внутрь инлайнового
|
||||||
|
<style type="text/tailwindcss"> в _base.html. Это обеспечивает единый
|
||||||
|
источник кастомных стилей для dev и prod
|
||||||
|
*/
|
||||||
|
@import "tailwindcss";
|
||||||
|
@import "../../lpon_site/templates/css/tailwind-custom.css";
|
||||||
|
|
||||||
|
/* Директива @source указывает Tailwind, ГДЕ искать реально используемые
|
||||||
|
классы (см. общее пояснение про @source выше, перед heredoc). Пути ниже
|
||||||
|
заданы относительно этого файла (frontend-assembly/tailwind/input.css),
|
||||||
|
поэтому "../../" ведёт в корень проекта. Если появятся новые каталоги с
|
||||||
|
разметкой/классами (например, отдельное приложение или папка partials
|
||||||
|
за пределами уже перечисленных путей), их нужно будет добавить сюда
|
||||||
|
отдельной строкой @source - иначе Tailwind не увидит использованные в
|
||||||
|
них классы и просто не включит их в итоговый tailwind.min.css. */
|
||||||
@source "../../lpon_site/templates/**/*.html";
|
@source "../../lpon_site/templates/**/*.html";
|
||||||
@source "../../lpon_site/frontend/**/*.py";
|
@source "../../lpon_site/frontend/**/*.py";
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
Reference in New Issue
Block a user