Tailwind CSS¶
Installation¶
tailwind CLI¶
Install nvm ->
- nvm (Node Version Manager) : Node.js의 버전 관리
- npm (Node Package Manager)
: JavaScript 패키지(라이브러리, 프레임워크 등)를 관리하고 설치하는 도구
: Node.js와 함께 제공되며 패키지의 설치, 업데이트, 삭제 등을 쉽게 처리할 수 있도록 도와준다
Step to Step (Docs-Tailwind CLI)
play CDN¶
Add the Play CDN script to your HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<h1 class="text-3xl font-bold underline">Hello world!</h1>
</body>
</html>
Step to Step (Docs-Play CDN)
Core Concepts¶
Utility-First Fundamentals¶
<!-- 기존 클래스를 HTML에 적용하여 스타일 지정 -->
<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center space-x-4">
<div class="shrink-0">
<img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div>
<div class="text-xl font-medium text-black">ChitChat</div>
<p class="text-slate-500">You have a new message!</p>
</div>
</div>
<!-- 스타일을 지정할 때마다 CSS 작성 -->
<div class="chat-notification">
<div class="chat-notification-logo-wrapper">
<img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div class="chat-notification-content">
<h4 class="chat-notification-title">ChitChat</h4>
<p class="chat-notification-message">You have a new message!</p>
</div>
</div>
<style>
.chat-notification {
display: flex;
max-width: 24rem;
margin: 0 auto;
padding: 1.5rem;
border-radius: 0.5rem;
background-color: #fff;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.chat-notification-logo-wrapper {
flex-shrink: 0;
}
.chat-notification-logo {
height: 3rem;
width: 3rem;
}
.chat-notification-content {
margin-left: 1.5rem;
padding-top: 0.25rem;
}
.chat-notification-title {
color: #1a202c;
font-size: 1.25rem;
line-height: 1.25;
}
.chat-notification-message {
color: #718096;
font-size: 1rem;
line-height: 1.5;
}
</style>
- flexbox, padding :
flex
,shrink-0
,p-6
- max-width, margin :
max-w-sm
,mx-auto
- background-color, border radius, box-shadow :
bg-white
,rounded-xl
,shadow-lg
- width, height :
w-12
,h-12
- space-between :
space-x-4
- font-size, text color, font-weight :
text-xl
,text-black
,font-medium
Tailwind CSS의 이점?
- You aren’t wasting energy inventing class names
- Your CSS stops growing
- Making changes feels safer
Hover, Focus, and Other States¶
Tailwind CSS modifiers¶
- Pseudo-classes :
:hover
,:focus
,:first-child
,:visited
, ...:{required}
- Pseudo-elements :
::before
,::after
,::placeholder
, ...::{selection}
- Media and feature queries :
prefers-reduced-motion
, 다크 모드, 반응형 breakpoint 등 - Attribute selectors :
[dir="rtl"]
,[open]
, ...
<ul role="list" class="p-6 divide-y divide-slate-200">
{#each people as person}
<!-- Remove top/bottom padding when first/last child -->
<li class="flex py-4 first:pt-0 last:pb-0">
<img class="h-10 w-10 rounded-full" src="{person.imageUrl}" alt="" />
<div class="ml-3 overflow-hidden">
<p class="text-sm font-medium text-slate-900">{person.name}</p>
<p class="text-sm text-slate-500 truncate">{person.email}</p>
</div>
</li>
{/each}
</ul>
<form>
<label class="block">
<span class="block text-sm font-medium text-slate-700">Username</span>
<!-- Using form state modifiers, the classes can be identical for every input -->
<input type="text" value="tbone" disabled class="mt-1 block w-full px-3 py-2 bg-white border border-slate-300 rounded-md text-sm shadow-sm placeholder-slate-400
focus:outline-none focus:border-sky-500 focus:ring-1 focus:ring-sky-500
disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none
invalid:border-pink-500 invalid:text-pink-600
focus:invalid:border-pink-500 focus:invalid:ring-pink-500
"/>
</label>
<!-- ... -->
</form>
Styling based on parent state¶
- group-{modifier} : 상위 요소의 상태에 따라 요소의 스타일을 지정해야 하는 경우
- group/{name} : 중첩된 그룹 구별
- group-* : 임시 부모 그룹 생성 (Arbitrary groups)
- peer-{modifier} : 형제 요소의 상태에 따라 요소의 스타일 지정
- peer-checked/{name} : 형제 요소 구별
- peer-* : 임시 형제 그룹 생성 (Arbitrary peers)
Example
<a href="#" class="group block max-w-xs mx-auto rounded-lg p-6 bg-white ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500">
<div class="flex items-center space-x-3">
<svg class="h-6 w-6 stroke-sky-500 group-hover:stroke-white" fill="none" viewBox="0 0 24 24"><!-- ... --></svg>
<h3 class="text-slate-900 group-hover:text-white text-sm font-semibold">New project</h3>
</div>
<p class="text-slate-500 group-hover:text-white text-sm">Create a new project from a variety of starting templates.</p>
</a>
Pseudo-classes, Pseudo-Element¶
- Before and after
- Placeholder text
- File input buttons
- List markers
- Highlighted text
- First-line and first-letter
- Dialog backdrops
<label class="block">
<span class="after:content-['*'] after:ml-0.5 after:text-red-500 block text-sm font-medium text-slate-700">
Email
</span>
<input type="email" name="email" class="mt-1 px-3 py-2 bg-white border shadow-sm border-slate-300 placeholder-slate-400 focus:outline-none focus:border-sky-500 focus:ring-sky-500 block w-full rounded-md sm:text-sm focus:ring-1" placeholder="you@example.com" />
</label>
<label class="relative block">
<span class="sr-only">Search</span>
<span class="absolute inset-y-0 left-0 flex items-center pl-2">
<svg class="h-5 w-5 fill-slate-300" viewBox="0 0 20 20"><!-- ... --></svg>
</span>
<input class="placeholder:italic placeholder:text-slate-400 block bg-white w-full border border-slate-300 rounded-md py-2 pl-9 pr-3 shadow-sm focus:outline-none focus:border-sky-500 focus:ring-sky-500 focus:ring-1 sm:text-sm" placeholder="Search for anything..." type="text" name="search"/>
</label>
Media and feature queries¶
- Responsive breakpoints
- Prefers color scheme : light, dark theme
- Prefers reduced motion
- Prefers contrast
- Viewport orientation
- Print styles
- Supports rules
Attribute selectors¶
- ARIA states
- RTL support
- Open/closed state
Custom modifiers¶
Responsive Design¶
- 반응형 웹 디자인 구축
Breakpoint prefix | Minimum width |
---|---|
sm | 640px |
md | 768px |
lg | 1024px |
xl | 1280px |
2xl | 1536px |
Example
<div class="max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl">
<div class="md:flex">
<div class="md:shrink-0">
<img class="h-48 w-full object-cover md:h-full md:w-48" src="/img/building.jpg" alt="Modern building architecture">
</div>
<div class="p-8">
<div class="uppercase tracking-wide text-sm text-indigo-500 font-semibold">Company retreats</div>
<a href="#" class="block mt-1 text-lg leading-tight font-medium text-black hover:underline">Incredible accommodation for your team</a>
<p class="mt-2 text-slate-500">Looking to take your team away on a retreat to enjoy awesome food and take in some sunshine? We have a list of places to do just that.</p>
</div>
</div>
</div>
- 기본적으로 바깥쪽의 div는 'display:block'으로 표시되기 때문에,
md:flex
를 추가하여 중간 화면(=md)부터는 'display:flex'로 표시합니다. - 부모 컨테이너가 flex인 경우 이미지가 축소되지 않기를 원하기 때문에, 중간 화면(=md)이상에서 축소되지 않도록
md:shrink-0
을 추가했습니다.
(비록 작은 화면에서는 아무것도 할 수 없으므로shrink-0
을 사용해도 무방하지만, md 화면에서만 문제가 되므로 명시하는 게 좋습니다) - Small screen에서는 이미지의 크기가 전체 너비로 자동 설정됩니다.
- medium screen에서는
md:h-full md:w-48
을 이용하여 너비를 고정된 크기로 제한하고, 이미지가 전체 높이가 되도록 설정했습니다.
스타일 재사용 Loops¶
<nav className="flex sm:justify-center space-x-4">
{[
['Home', '/dashboard'],
['Team', '/team'],
['Projects', '/projects'],
['Reports', '/reports'],
].map(([title, url]) => (
<a href={url} className="rounded-lg px-3 py-2 text-slate-700 font-medium hover:bg-slate-100 hover:text-slate-900">{title}</a>
))}
</nav>
사용자 정의 스타일 추가¶
Quote
- Docs
- openai