Ruby on Rails 8 – Fast Frontend با استفاده از Tailwind به عنوان یک چارچوب CSS بدون کلاس

این مقاله به عمد بسیار شبیه به مقالات قبلی این مجموعه است، اما این بار از فریم ورک Tailwind به عنوان یک فریمورک بدون کلاس css استفاده خواهیم کرد. از مقاله CSS بدون کلاس بر اساس Tailwind الهام گرفته شده است
یک برنامه جدید Rails را شروع کنید
- O
time
قبل از فرمانrails
برای نمایش زمان اجرای آن در پایان اجرای دستور عمل می کند. در مثال زیر 47 ثانیه طول کشید.
$ rails -v
Rails 8.0.0
$ time rails new classless-css-tailwind
...
real 0m47.500s
user 0m33.052s
sys 0m4.249s
Rails 8، در فلسفه No Build خود، از Propshaft به عنوان یک کتابخانه خط لوله دارایی و Importmap به عنوان کتابخانه جاوا اسکریپت به طور پیش فرض استفاده می کند. Importmap هیچ گونه پردازش جاوا اسکریپت را انجام نمی دهد.
پروژه را با VSCode یا ویرایشگر دلخواه خود باز کنید
$ cd classless-css-tailwind && code .
ایجاد چند صفحه برای تجسم استایل عناصر HTML
صفحات در اولین مقاله این مجموعه در مراحل مشترک هستند.
فایل Tailwind را تغییر دهید فایل بالا را تغییر دهید تا ارجاع به فایلهای با استایل Tailwind CSS را در خود داشته باشد. توجه داشته باشید که فقط یک خمیر ایجاد کنید app/assets/stylesheets/application.tailwind.css
نمایش بیشتر…
Opção 1
بدون اظهار نظر است./* INSIRA OS CSS CUSTOMIZADOS DO TAILWIND NA PARTE SUPERIOR */
/* SE O "@tailwind base", "@tailwind components" E "@tailwind utilities" NÃO ESTIVEREM COMENTADOS */
/* Opção 1: Verde */
@import "./custom_tailwind/custom1.css";
/* Opção 2: Azul */
/* @import "./custom_tailwind/custom2.css"; */
/* Opção3: Do artigo "Classless CSS based on Tailwind" */
/* https://medium.com/@AntonShevchuk/classless-css-based-on-tailwind-57d4ef745c1f */
/* @import "./custom_tailwind/custom3.css"; */
/* @tailwind base;
@tailwind components;
@tailwind utilities; */
custom_tailwind
داخل دایرکتوری app/assets/stylesheets/
برای افزودن فایل های سفارشی Tailwind.
محتوای اولین فایل سفارشی Tailwind را در آن قرار دهید فایل را ایجاد کنید custom1.css
نمایش بیشتر…
app/assets/stylesheets/custom_tailwind/custom1.css
و مطالب زیر را کپی کنید/*
Visão geral:
Unificação de variáveis de tema (ao invés de --background-light e --background-dark, temos apenas --background, e assim por diante).
Redução de duplicações de @media (prefers-color-scheme: dark). Boa parte do tema escuro está centralizado no :root.
Usamos variáveis no lugar das cores diretas e, em alguns pontos, aproveitar a nomenclatura do Tailwind.
Caso utilize o modo escuro via classes (class="dark") em vez de prefers-color-scheme,
a lógica seria um pouco diferente (usando dark:bg-*, dark:text-*, etc.).
Mas, conforme as recomendações, mantivemos o @media (prefers-color-scheme: dark) para respeitar as preferências do usuário.
1. Variáveis de tema unificadas
Agora temos --background, --text e --accent (entre outras) em vez de --background-light, --background-dark, etc.
Isso reduz a repetição e deixa o código mais fácil de manter.
2. Menos repetições de @media (prefers-color-scheme: dark)
Quase tudo para o tema escuro foi concentrado em um único bloco, dentro do :root.
Assim, sempre que o usuário preferir o modo escuro, todas as variáveis são redefinidas.
3. Uso de variáveis complementares
Adicionamos --background-code, --border, --form-border e --focus-ring para garantir que todas as cores que possam variar
conforme o tema sejam facilmente alteradas.
4. Estilos de formulário otimizados
Em vez de separar cada tipo de input em vários blocos, unificamos a maioria deles.
Evita duplicações e mantém uma consistência de design.
---
Observações Finais
Se quiser seguir ainda mais o padrão do Tailwind sem tantas variáveis, você poderia usar as classes utilitárias padrão
(bg-gray-50, text-gray-900, dark:bg-gray-800, dark:text-gray-100, etc.).
Para quem prefere o modo escuro via classe .dark, bastaria trocar o @media (prefers-color-scheme: dark)
por seletores .dark & { ... } no arquivo e controlar o tema em JavaScript ou manualmente no HTML ().
*/
/*
|-----------------------------------------------------------------------------
| IMPORTA O TAILWIND CSS
|-----------------------------------------------------------------------------
| Aqui importamos as diretivas do Tailwind para carregar o CSS base,
| componentes e utilitários. Isso garante que todas as funcionalidades
| essenciais do Tailwind sejam carregadas antes de adicionarmos
| nossas customizações.
*/
@tailwind base;
@tailwind components;
@tailwind utilities;
/*
|-----------------------------------------------------------------------------
| VARIÁVEIS CSS PARA TEMAS CLARO/ESCURO
|-----------------------------------------------------------------------------
| Agora, unificamos as variáveis para evitar duplicação. Em vez de termos
| --background-light e --background-dark, temos apenas --background e
| mudamos seu valor no @media (prefers-color-scheme: dark).
*/
:root {
/* Tema claro (default) */
--background: #ffffff; /* Fundo do site */
--text: #292929; /* Cor principal do texto */
--accent: #1a8917; /* Cor de destaque (links, botões, etc.) */
/* Variáveis complementares para uso em elementos específicos */
--background-code: #f3f4f6; /* Fundo de blocos de código no claro */
--border: #e5e7eb; /* Cor de borda padrão (claro) */
--form-border: #d1d5db; /* Cor de borda padrão para formulários (claro) */
--focus-ring: #1a8917; /* Cor do anel de foco (claro) */
}
@media (prefers-color-scheme: dark) {
:root {
/* Tema escuro */
--background: #121212; /* Fundo do site */
--text: #e6e6e6; /* Cor principal do texto */
--accent: #4caf50; /* Cor de destaque (links, botões, etc.) */
/* Variáveis complementares */
--background-code: #1f2937; /* Fundo de blocos de código no escuro */
--border: #374151; /* Cor de borda padrão (escuro) */
--form-border: #4b5563; /* Cor de borda padrão para formulários (escuro) */
--focus-ring: #4caf50; /* Cor do anel de foco (escuro) */
}
}
/*
|-----------------------------------------------------------------------------
| ESTILOS BASE
|-----------------------------------------------------------------------------
| A camada base (layer base) permite que possamos sobrescrever
| estilos padrão do browser e aplicar resets ou estéticas iniciais.
| Aqui fazemos o 'apply' de classes Tailwind diretamente em tags HTML
| para criar estilos globais.
*/
@layer base {
/*
|-----------------------------------------------------------------------------
| HTML
|-----------------------------------------------------------------------------
| O recebe o antialiased (que melhora a renderização de fontes),
| além das cores de fundo e texto baseadas em nossas variáveis.
*/
html {
@apply antialiased;
background-color: var(--background);
color: var(--text);
}
/*
|-----------------------------------------------------------------------------
| BODY
|-----------------------------------------------------------------------------
| Aqui definimos o espaçamento interno (padding) para o corpo do site
| e uma largura máxima de 4xl, centralizando (mx-auto) para que o
| conteúdo não fique muito extenso em telas grandes.
*/
body {
@apply mx-auto max-w-4xl px-4 leading-relaxed sm:px-6 lg:px-8;
}
/*
|-----------------------------------------------------------------------------
| TÍTULOS (H1, H2, H3, etc.)
|-----------------------------------------------------------------------------
| Definimos tamanhos de fonte diferentes para cada nível de título,
| além de margens inferiores para separar visualmente do texto seguinte.
| Também usamos breakpoints (sm:) para modificar o tamanho em telas maiores.
*/
/* h1 {
@apply mb-8 text-4xl font-bold leading-tight sm:text-5xl;
}
h2 {
@apply mb-6 text-3xl font-bold leading-tight sm:text-4xl;
}
h3 {
@apply mb-4 text-2xl font-bold sm:text-3xl;
}
h4 {
@apply mb-4 text-xl font-bold;
}
h5 {
@apply mb-4 text-lg font-bold;
}
h6 {
@apply mb-4 text-base font-bold;
} */
/* Principais mudanças feitas:
1. Removemos os breakpoints `sm:` fixos e substituímos por `clamp()`
2. A função `clamp()` aceita três valores:
- Valor mínimo (para telas pequenas)
- Valor preferido (calculado usando viewport width)
- Valor máximo (para telas grandes)
3. A fórmula geral usada é:
- Para títulos: percentual do viewport (vw) + valor base em rem
- Para texto regular: valor menor do viewport + valor base menor
4. Os valores foram escolhidos para criar uma transição suave entre:
- Telas móveis (320px+)
- Tablets (768px+)
- Desktops (1024px+)
- Telas grandes (1440px+)
Esta implementação oferece várias vantagens:
- Transição mais suave entre tamanhos de tela
- Elimina "saltos" abruptos nos breakpoints
- Mantém a legibilidade em todos os tamanhos de tela
- Reduz a quantidade de código necessário
- Proporciona uma experiência mais fluida aos usuários */
h1 {
@apply mb-8 font-bold leading-tight;
font-size: clamp(2.25rem, 5vw + 1rem, 3.5rem);
}
h2 {
@apply mb-6 font-bold leading-tight;
font-size: clamp(1.875rem, 4vw + 0.5rem, 2.75rem);
}
h3 {
@apply mb-4 font-bold;
font-size: clamp(1.5rem, 3vw + 0.5rem, 2.25rem);
}
h4 {
@apply mb-4 font-bold;
font-size: clamp(1.25rem, 2vw + 0.5rem, 1.75rem);
}
h5 {
@apply mb-4 font-bold;
font-size: clamp(1.125rem, 1.5vw + 0.5rem, 1.5rem);
}
h6 {
@apply mb-4 font-bold;
font-size: clamp(1rem, 1vw + 0.5rem, 1.25rem);
}
/*
|-----------------------------------------------------------------------------
| PARÁGRAFOS (P) E TEXTO EM GERAL
|-----------------------------------------------------------------------------
| Damos um espaçamento (margin-bottom) e um tamanho de fonte confortável.
| sm:text-xl faz com que, em telas no breakpoint "sm" (ex: >= 640px),
| o texto fique maior.
*/
/* p {
@apply mb-6 text-lg leading-relaxed sm:text-xl;
} */
p {
@apply mb-6 leading-relaxed;
font-size: clamp(1rem, 1.5vw + 0.5rem, 1.25rem);
}
/*
|-----------------------------------------------------------------------------
| LINKS (A)
|-----------------------------------------------------------------------------
| Usamos a cor de destaque (var(--accent)) e sublinhado.
| O :hover diminui a opacidade para dar um efeito de feedback ao usuário.
*/
a {
color: var(--accent);
@apply hover:underline hover:opacity-80;
}
/*
|-----------------------------------------------------------------------------
| TEXTO EM NEGRITO (STRONG) E ITÁLICO (EM)
|-----------------------------------------------------------------------------
| Mantemos a semântica e a ênfase visualmente clara.
*/
strong {
@apply font-bold;
}
em {
@apply italic;
}
/*
|-----------------------------------------------------------------------------
| LISTAS (UL, OL)
|-----------------------------------------------------------------------------
| Definimos margens, padding à esquerda e estilos de lista (disc, decimal).
*/
ul,
ol {
@apply mb-6 pl-8;
}
/* li {
@apply mb-2 text-lg sm:text-xl;
} */
li {
@apply mb-2;
font-size: clamp(1rem, 1.5vw + 0.5rem, 1.25rem);
}
ul > li {
@apply list-disc;
}
ol > li {
@apply list-decimal;
}
/*
|-----------------------------------------------------------------------------
| BLOCOS DE CÓDIGO (PRE, CODE)
|-----------------------------------------------------------------------------
| Usados para exibir trechos de código de forma destacada.
| O overflow-x-auto faz com que apareça scroll horizontal em códigos longos.
*/
pre {
@apply mb-6 overflow-x-auto rounded-lg p-4;
background-color: var(--background-code);
}
code {
@apply rounded px-1 font-mono text-sm;
background-color: var(--background-code);
}
/*
|-----------------------------------------------------------------------------
| BLOCKQUOTE (CITAÇÕES)
|-----------------------------------------------------------------------------
| Recuo (padding-left), texto em itálico e borda esquerda na cor de destaque.
*/
blockquote {
@apply mb-6 pl-4 italic;
border-left: 4px solid var(--accent);
}
/*
|-----------------------------------------------------------------------------
| TABELAS (TABLE, TH, TD)
|-----------------------------------------------------------------------------
| Tabelas ocupando toda a largura (w-full) e sem espaços entre as células
| (border-collapse). Também definimos bordas para separar conteúdo.
*/
table {
@apply mb-6 w-full border-collapse;
}
th {
@apply p-2 text-left font-bold;
border-bottom: 2px solid var(--border);
}
td {
@apply p-2;
border-bottom: 1px solid var(--border);
}
/*
|-----------------------------------------------------------------------------
| FORMULÁRIOS (INPUT, TEXTAREA, SELECT)
|-----------------------------------------------------------------------------
| Unificamos a estilização para vários tipos de input:
| - Todos terão largura cheia (w-full), padding, bordas arredondadas e
| cor de fundo conforme o tema.
| - A borda usa nossa variável de cor de borda.
*/
input[type="email"],
input[type="password"],
input[type="search"],
input[type="text"],
input[type="url"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input[type="time"],
input[type="tel"],
select[multiple],
input,
textarea,
select {
@apply w-full rounded-lg p-2;
background-color: var(--background);
border: 1px solid var(--form-border);
}
/*
|-----------------------------------------------------------------------------
| ESTADO DE FOCUS EM FORMULÁRIOS
|-----------------------------------------------------------------------------
| outline-none remove as bordas padrão do navegador,
| e adicionamos um box-shadow para indicar que está em foco.
*/
input[type="email"]:focus,
input[type="password"]:focus,
input[type="search"]:focus,
input[type="text"]:focus,
input[type="url"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
input[type="datetime-local"]:focus,
input[type="month"]:focus,
input[type="week"]:focus,
input[type="time"]:focus,
input[type="tel"]:focus,
select[multiple]:focus,
input:focus,
textarea:focus,
select:focus {
@apply outline-none;
box-shadow: 0 0 0 2px var(--focus-ring);
}
/*
|-----------------------------------------------------------------------------
| BOTÕES (BUTTON, INPUT[TYPE=BUTTON/SUBMIT/RESET/FILE])
|-----------------------------------------------------------------------------
| Usamos a cor de destaque (accent) para o fundo e o texto fica branco.
| Adicionamos hover e transition para ficar mais agradável ao usuário.
*/
input[type="button"],
input[type="submit"],
input[type="reset"],
::file-selector-button,
button {
@apply rounded-lg px-4 py-2 text-white transition-opacity hover:opacity-90;
background-color: var(--accent);
}
/*
|-----------------------------------------------------------------------------
| IMAGENS E MÍDIA (IMG, VIDEO, AUDIO)
|-----------------------------------------------------------------------------
| As imagens terão largura máxima de 100% (max-w-full) e altura automática
| (h-auto) para ficarem responsivas, centralizadas (ms-auto), além de bordas arredondadas (rounded-lg).
*/
img {
@apply mx-auto mb-6 h-auto max-w-full rounded-lg hover:scale-[1.02];
}
/* Figcaption (legendas de imagem) */
figcaption {
@apply mt-2 text-sm italic;
text-align: center;
}
video,
audio {
@apply mb-6 w-full;
}
/*
|-----------------------------------------------------------------------------
| DIVISORES (HR)
|-----------------------------------------------------------------------------
| Linha horizontal para separar seções de conteúdo.
| Usamos var(--border) para a cor da borda, de acordo com o tema.
*/
hr {
@apply my-8;
border-top: 1px solid var(--border);
}
}
/*
|-----------------------------------------------------------------------------
| UTILITÁRIOS PERSONALIZADOS
|-----------------------------------------------------------------------------
| A camada utilities (layer utilities) é onde definimos classes utilitárias
| adicionais, caso as classes do Tailwind não cubram nossas necessidades.
*/
@layer utilities {
/*
|-----------------------------------------------------------------------------
| CONTENT-WRAPPER
|-----------------------------------------------------------------------------
| Caso queiramos reaproveitar o max-w-4xl e o mx-auto + px-4 em um
| container específico.
*/
.content-wrapper {
@apply mx-auto max-w-4xl px-4;
}
/*
|-----------------------------------------------------------------------------
| TEXT-BALANCE
|-----------------------------------------------------------------------------
| Propriedade moderna (text-wrap: balance) que melhora a distribuição
| de palavras, mas não é suportada em todos os navegadores.
| Lembre de testar compatibilidade.
*/
.text-balance {
text-wrap: balance;
}
/*
|-----------------------------------------------------------------------------
| PROSE
|-----------------------------------------------------------------------------
| Caso queira um estilo de texto ao estilo "prose" do Tailwind, mas
| sem o limite padrão de largura.
*/
.prose {
@apply max-w-none;
}
/*
|-----------------------------------------------------------------------------
| PROSE > IMG
|-----------------------------------------------------------------------------
| Exemplo de como centralizar imagens dentro de um container .prose.
*/
.prose img {
@apply mx-auto;
}
}
/*
---
*/
محتویات دومین فایل سفارشی Tailwind را در آن قرار دهید فایل را ایجاد کنید custom2.css
نمایش بیشتر…
app/assets/stylesheets/custom_tailwind/custom2.css
و مطالب زیر را کپی کنید/* =================================================================
CONFIGURAÇÃO DE VARIÁVEIS CSS
Definição centralizada de todas as variáveis do projeto
================================================================= */
:root {
/* Cores - Tema Claro */
--color-primary: #2563eb; /* blue-600 do Tailwind */
--color-primary-hover: #1d4ed8; /* blue-700 do Tailwind */
--color-background: #ffffff;
--color-text: #1f2937; /* gray-800 do Tailwind */
--color-text-muted: #4b5563; /* gray-600 do Tailwind */
--color-border: #d1d5db; /* gray-300 do Tailwind */
--color-input-bg: #f9fafb; /* gray-50 do Tailwind */
--color-code-bg: #f3f4f6; /* gray-100 do Tailwind */
--color-code-text: #273e65; /* blue-800 do Tailwind */
/* Espaçamento */
--spacing-base: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
/* Border Radius */
--radius-base: 0.375rem;
--radius-lg: 0.5rem;
/* Larguras Máximas */
--max-width-content: 48rem; /* 768px */
}
/* Configuração do tema escuro usando prefers-color-scheme */
@media (prefers-color-scheme: dark) {
:root {
/* Cores - Tema Escuro */
--color-primary: #0284c7; /* sky-600 do Tailwind */
--color-primary-hover: #6990c7; /* blue-400 do Tailwind */
--color-background: #111827; /* gray-900 do Tailwind */
--color-text: #f3f4f6; /* gray-100 do Tailwind */
--color-text-muted: #9ca3af; /* gray-400 do Tailwind */
--color-border: #374151; /* gray-700 do Tailwind */
--color-input-bg: #1f2937; /* gray-800 do Tailwind */
--color-code-bg: #1f2937; /* gray-800 do Tailwind */
--color-code-text: #e8ecf6; /* blue-100 do Tailwind */
}
}
/* Importações do Tailwind */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* =================================================================
ESTILOS BASE
Configurações globais e reset de elementos HTML
================================================================= */
@layer base {
body {
@apply mx-auto max-w-3xl px-4 leading-relaxed tracking-wide sm:px-6 md:px-8 lg:px-12;
background-color: var(--color-background);
color: var(--color-text);
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif;
line-height: clamp(1.5, 2vw + 1.2, 1.75);
}
/* Links */
a {
color: var(--color-primary);
@apply hover:underline;
}
/* Títulos - Usando variáveis CSS para tamanhos consistentes */
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: var(--spacing-lg);
margin-bottom: var(--spacing-base);
@apply font-bold leading-tight;
}
/* Sistema de escala tipográfica responsiva */
/* h1 {
@apply text-3xl sm:text-4xl md:text-5xl;
}
h2 {
@apply text-2xl sm:text-3xl md:text-4xl;
}
h3 {
@apply text-xl sm:text-2xl md:text-3xl;
}
h4 {
@apply text-lg sm:text-xl md:text-2xl;
}
h5 {
@apply text-base sm:text-lg md:text-xl;
}
h6 {
@apply text-sm sm:text-base md:text-lg;
} */
/* Sistema de escala tipográfica fluida usando clamp() */
h1 {
font-size: clamp(2rem, 5vw + 1rem, 3.5rem);
}
h2 {
font-size: clamp(1.75rem, 4vw + 0.75rem, 3rem);
}
h3 {
font-size: clamp(1.5rem, 3vw + 0.75rem, 2.5rem);
}
h4 {
font-size: clamp(1.25rem, 2vw + 0.75rem, 2rem);
}
h5 {
font-size: clamp(1.1rem, 1.5vw + 0.75rem, 1.5rem);
}
h6 {
font-size: clamp(1rem, 1vw + 0.75rem, 1.25rem);
}
/* Elementos de texto */
/* p {
margin-bottom: var(--spacing-base);
@apply text-lg leading-relaxed;
} */
/* Parágrafos com tipografia fluida */
p {
margin-bottom: var(--spacing-base);
font-size: clamp(1rem, 1.5vw + 0.75rem, 1.25rem);
line-height: clamp(1.6, 2vw + 1.2, 1.8);
}
/* Listas */
ul,
ol {
margin-bottom: var(--spacing-base);
padding-left: var(--spacing-lg);
}
ul {
@apply list-disc;
}
ol {
@apply list-decimal;
}
/* li {
margin-bottom: calc(var(--spacing-base) * 0.5);
} */
/* Elementos de lista com tipografia fluida */
li {
margin-bottom: calc(var(--spacing-base) * 0.5);
font-size: clamp(1rem, 1.5vw + 0.75rem, 1.25rem);
}
/* Imagens responsivas */
img {
@apply h-auto w-full;
border-radius: var(--radius-lg);
margin: var(--spacing-base) 0;
}
/* Citações */
/* blockquote {
border-left: 4px solid var(--color-border);
color: var(--color-text-muted);
padding-left: var(--spacing-base);
@apply my-4 italic;
} */
/* Código inline e blocos de código */
/* code {
background-color: var(--color-code-bg);
color: var(--color-code-text);
border-radius: var(--radius-base);
@apply px-1 py-0.5 text-sm;
} */
/* pre {
background-color: var(--color-code-bg);
border-radius: var(--radius-lg);
padding: var(--spacing-base);
@apply overflow-x-auto text-sm;
} */
/* Citações com tipografia fluida */
blockquote {
border-left: 4px solid var(--color-border);
color: var(--color-text-muted);
padding-left: var(--spacing-base);
@apply my-4 italic;
font-size: clamp(1rem, 1.5vw + 0.75rem, 1.25rem);
}
/* Código inline com tipografia fluida */
code {
background-color: var(--color-code-bg);
color: var(--color-code-text);
border-radius: var(--radius-base);
@apply px-1 py-0.5;
font-size: clamp(0.875rem, 1vw + 0.5rem, 1rem);
}
/* Blocos de código com tipografia fluida */
pre {
background-color: var(--color-code-bg);
border-radius: var(--radius-lg);
padding: var(--spacing-base);
@apply overflow-x-auto;
font-size: clamp(0.875rem, 1vw + 0.5rem, 1rem);
}
/* Tabelas */
table {
@apply my-4 w-full border-collapse;
}
/* th,
td {
border-bottom: 1px solid var(--color-border);
padding: calc(var(--spacing-base) * 0.5) var(--spacing-base);
@apply text-left;
} */
/* Células de tabela com tipografia fluida */
th, td {
border-bottom: 1px solid var(--color-border);
padding: calc(var(--spacing-base) * 0.5) var(--spacing-base);
@apply text-left;
font-size: clamp(0.875rem, 1vw + 0.5rem, 1rem);
}
th {
background-color: var(--color-code-bg);
@apply font-semibold;
}
/* Formulários */
input[type="email"],
input[type="password"],
input[type="search"],
input[type="text"],
input[type="url"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input[type="time"],
input[type="tel"],
select[multiple],
input,
textarea,
select,
button {
border-radius: var(--radius-base);
margin-bottom: var(--spacing-base);
padding: calc(var(--spacing-base) * 0.5) var(--spacing-base);
width: 100%;
border: 1px solid var(--color-border);
}
::file-selector-button {
border-radius: var(--radius-base);
margin-bottom: var(--spacing-base);
padding: calc(var(--spacing-base) * 0.5) var(--spacing-base);
border: 1px solid var(--color-border);
}
/* Campos de formulário */
input[type="email"],
input[type="password"],
input[type="search"],
input[type="text"],
input[type="url"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input[type="time"],
input[type="tel"],
select[multiple],
input,
textarea,
select {
background-color: var(--color-input-bg);
color: var(--color-text);
}
/* Estados de foco */
input[type="email"]:focus,
input[type="password"]:focus,
input[type="search"]:focus,
input[type="text"]:focus,
input[type="url"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
input[type="datetime-local"]:focus,
input[type="month"]:focus,
input[type="week"]:focus,
input[type="time"]:focus,
input[type="tel"]:focus,
select[multiple]:focus,
input:focus,
textarea:focus,
select:focus {
@apply outline-none ring-2 ring-blue-500 focus:ring-offset-2;
}
/* Botões */
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
::file-selector-button {
background-color: var(--color-primary);
color: white;
@apply cursor-pointer hover:bg-blue-700;
}
}
/* =================================================================
COMPONENTES
Classes reutilizáveis para padrões comuns de design
================================================================= */
@layer components {
.container-page {
margin: 0 auto;
max-width: var(--max-width-content);
padding: 0 var(--spacing-base);
@apply sm:px-6 md:px-8 lg:px-12;
}
.table-striped tbody tr:nth-of-type(odd) {
background-color: var(--color-input-bg);
}
.code-block {
background-color: var(--color-code-bg);
border-radius: var(--radius-lg);
padding: var(--spacing-base);
@apply overflow-x-auto text-sm;
}
}
/* =================================================================
UTILITÁRIOS
Classes utilitárias personalizadas
================================================================= */
@layer utilities {
.text-primary {
color: var(--color-primary);
}
.bg-primary {
background-color: var(--color-primary);
}
}
محتویات سومین فایل سفارشی Tailwind را در آن قرار دهید فایل را ایجاد کنید " ";
@apply ml-1 pl-2;
@apply border-l-4 border-l-amber-500;
@apply mr-1 block text-base text-sky-700;
}
&::after {
content: " custom3.css
نمایش بیشتر…
app/assets/stylesheets/custom_tailwind/custom3.css
و مطالب زیر را کپی کنید@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
body {
@apply min-h-screen bg-gradient-to-t from-slate-50 to-slate-200 text-slate-950;
}
h1 {
@apply px-4 py-8 text-2xl;
}
h2 {
@apply px-4 py-4 text-xl;
}
h3 {
@apply px-4 pb-1 pt-2 text-xl;
}
h4,
h5,
h6 {
@apply px-4 pb-0 pt-1 text-lg;
}
a {
@apply underline decoration-sky-800 underline-offset-2;
}
a:hover {
@apply decoration-2;
}
header,
main,
footer {
@apply container max-w-3xl;
}
header {
@apply mt-4 rounded-t-lg border border-slate-300 bg-slate-50;
h1 {
@apply pb-1 text-slate-900;
}
h2 {
@apply font-normal text-slate-700;
}
p {
@apply px-4 py-4 pt-0 text-base font-normal text-slate-500;
}
}
main {
@apply border-l border-r border-slate-300 bg-white;
article {
@apply py-2;
p {
@apply p-4 px-4 text-justify text-base leading-normal;
img {
@apply float-start m-3 rounded border border-gray-300 p-1;
}
}
blockquote {
@apply mx-4 p-4 px-4 text-justify text-base leading-normal text-slate-500;
@apply border-l-4 border-l-slate-500;
}
ul {
@apply m-4 rounded border border-gray-100;
@apply divide-y divide-gray-200;
li {
@apply p-4;
p {
@apply my-0;
}
}
}
span {
@apply text-base leading-normal;
}
button[type="button"] {
@apply my-2 ml-4 rounded bg-amber-200 px-2 py-1;
&:hover {
@apply transition hover:bg-amber-500;
}
}
}
form {
@apply p-4;
fieldset {
@apply rounded border border-gray-300 p-4;
}
input,
textarea,
select,
button {
@apply my-2 rounded border border-gray-300 p-2 shadow-sm;
@apply ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-slate-800;
&:disabled {
@apply border-gray-100 ring-gray-200 focus:ring-gray-500;
&:checked {
@apply bg-gray-200;
}
}
}
input:disabled + label {
@apply text-gray-500;
}
select {
@apply w-96 rounded-md border-0 py-1.5;
}
button {
@apply transition hover:bg-slate-200;
}
}
}
footer {
@apply mb-4 rounded-b-lg border border-slate-300 bg-slate-50 p-4;
}
aside {
@apply absolute right-0 top-0 m-4 max-h-[90vh] w-96 overflow-auto p-2;
@apply rounded-md border border-slate-300 bg-white shadow;
&[id="output"] {
@apply left-0;
code {
@apply max-h-[90vh] overflow-y-scroll leading-4;
}
}
nav {
@apply top-0 flex justify-between bg-white;
a {
@apply rounded px-2 py-1 no-underline;
&:hover {
@apply transition hover:bg-slate-200;
}
&[rel="prev"]:before {
content: "←";
@apply mr-0.5;
}
&[rel="index"]:before {
content: "§";
@apply mr-0.5;
}
&[href="#"]:after {
content: "↻";
@apply ml-0.5;
}
&[rel="next"]:after {
content: "→";
@apply ml-0.5;
}
}
}
div {
@apply max-h-[80vh] overflow-y-scroll;
}
hr {
@apply mx-1 my-2;
}
p {
@apply p-2 text-base;
}
code {
@apply mt-2 block whitespace-pre-wrap px-2 py-1 leading-normal;
}
input {
@apply m-0.5 p-1 font-mono text-base;
}
label {
@apply m-0.5 px-0.5 font-mono text-base font-bold;
}
button[type="button"] {
@apply my-1 min-w-24 rounded bg-slate-100 px-2 py-1;
&:hover {
@apply transition hover:bg-slate-200;
}
}
}
}
@layer components {
code {
@apply relative inline-block rounded bg-slate-50 px-1 py-0.5 font-mono;
span {
@apply text-green-600;
}
em {
@apply text-gray-500;
}
i {
@apply not-italic text-red-800;
}
&[contenteditable] {
@apply border border-green-100 bg-green-50;
}
&[contenteditable]::after {
content: "✎";
@apply absolute right-0 top-0 m-1 inline-flex h-6 w-6 items-center justify-center;
@apply rounded-full bg-amber-100 text-sm font-semibold text-black;
}
}
.accordion {
article {
@apply p-0;
h3 {
@apply border-b border-slate-300 bg-slate-100;
@apply cursor-pointer;
background-image: url(../images/arrows.png);
background-position: 98% 12px;
background-repeat: no-repeat;
&:hover {
@apply bg-slate-200;
}
}
p {
@apply hidden border-b border-slate-300;
}
}
}
.events {
@apply list-none p-0;
li {
@apply p-[2px];
}
li span {
@apply mx-1 mr-2 inline-block min-w-6 rounded-full bg-amber-400 px-1 text-center text-white;
}
}
}
@layer utilities {
.formatter {
h1,
h2,
h3 {
@apply px-4 pb-1 pt-2 text-lg text-slate-900;
}
h1 {
&::before {
content: ";
@apply mx-2 text-base text-sky-700;
}
&::after {
content: "";
@apply mx-2 text-base text-sky-700;
}
}
h2 {
&::before {
content: "
"
;
@apply mx-2 text-base text-sky-700;
}
&::after {
content: "";
@apply mx-2 text-base text-sky-700;
}
}
h3 {
&::before {
content: ""
;
@apply mx-1 ml-2 text-base text-sky-700;
}
&::after {
content: "";
@apply mx-1 text-base text-sky-700;
}
}
p {
@apply ml-2;
&::before {
content: "
کلاس های Tailwind را از فایل حذف کنید در آرشیو app/views/layouts/application.html.erb
نمایش بیشتر…
application.html.erb
، برچسب را حذف یا نظر دهید ، که قبل و بعد از تگ است
<%= yield %>
به طوری که رفتار استایل سفارشی که برای Tailwind ایجاد کردیم تغییر نکند. <%# <main class="container mx-auto mt-28 px-5 flex"> %>
<%= yield %>
<%# main> %>
برخی از مراحل اضافی برای کارآمد کردن یک ظاهر طراحی شده به فایلهای Tailwind سفارشی. اگر مراحل قبلی را دنبال کردید، فایل فقط باید یک سبک بدون نظر وجود داشته باشد. برای تست یک سبک دیگر، ابتدا در مورد استایلی که در حال حاضر استفاده میشود نظر دهید و سبک دیگری را که میخواهید تست کنید، لغو نظر کنید. پس از انتخاب یکی از سبک های سفارشی موجود، دستور زیر را اجرا کنید: اگر دستور قبلی برای استایل دادن به عناصر HTML کار نمیکند، ابتدا فایلهای قبلی را پاکسازی کرده و دوباره از پیش کامپایل کنید:
نمایش بیشتر…
app/assets/stylesheets/application.tailwind.css
فقط باید خط داشته باشد @import "./custom_tailwind/custom1.css";
بدون نظر$ bin/rails assets:precompile
$ bin/dev
$ bin/rails assets:clobber
$ bin/rails assets:precompile
$ bin/dev
اکنون، مقداری استایل HTML با استفاده از Tailwind به عنوان یک چارچوب بدون کلاس 🤩
پس از پیکربندی Tailwind با سفارشیسازیهای بالا و راهاندازی سرور Rails، HTML استایلشده خود را خواهید دید.
حالت تاریک
برخی از سبک ها گزینه ای برای حالت تاریک دارند. برای تأیید، موضوع رایانه خود را در گزینههای سفارشیسازی رنگ تغییر دهید. ویندوز را جستجو کنید Ativar modo escuro para apps
و بین حالت تاریک یا روشن سوئیچ کنید. صفحه HTML باید پس از تغییر سیستم عامل به طور خودکار تغییر کند که نشان می دهد از حالت روشن و تاریک پشتیبانی می کند.
مراحل بعدی
[x] سبک ها را بر اساس ترجیح خود سازماندهی کنید.
[x] استفاده از یک ظاهر طراحی شده از فایل های CSS پروژه، بدون استفاده از CDN.
[x] قابلیتهای یک چارچوب CSS بدون کلاس را با استفاده از Tailwind تکرار کنید.
[-] تغییرات ایجاد شده در پروژه را با استفاده از مرورگر به صورت پویا به روز کنید Rails Live Reload
;
[-] اگر می خواهید زمان بیشتری را در قسمت جلویی بگذرانید، گزینه های سفارشی سازی سبک مورد علاقه خود را بررسی کنید.
مراجع