[ 살펴보기 ] TailwindCSS - Hover, groups and more
![[ 살펴보기 ] TailwindCSS - Hover, groups and more](https://cdn.hashnode.com/res/hashnode/image/upload/v1725519510339/3d48dccb-0f87-417e-8602-51f30a425862.jpeg)
TailwindCSS를 통해 Tailwind가 제공하는 utility class를 설정하여 style을 적용하는 것 외에 hover, focus와 같은 action에 따른 style 적용이나 responseive style적용 또한 가능하다.
Hover, focus and more
특정 element를 hover했을 때 다른 style을 적용하고 싶다면 다음과 같이 hover:style 형식으로 스타일을 적용한다.
<h1 className="text-xl hover:text-2xl">Title</h1>
만약 hover시 text 크기 뿐만 아니라 색상 역시 변경해야 한다면 hover modifier를 하나 더 추가 해준다.
<h1 className="text-xl hover:text-2xl hover:text-green-500">Title</h1>
위의 예제에서 h1 element에 mouse를 hover하면 text 크기가 2xl 사이즈로 변경되고 text color 역시 변경된다.
Hover외에 다른 state modifier 역시 사용할 수 있다.
<h1 className="text-xl active:text-green-500">Title</h1>
<input
type="text"
className="border text-blue-300 focus:text-blue-700"
/>
Frist-of-type
Hover나 active와 같은 상태 action이외에 first-of-type이나 last-of-type과 같은 pseudo class 역시 사용할 수 있다.
다음 예제에서 list 숫자 만큼 p element가 display될 때 첫 번째 p element의 text color를 blue-400으로 설정하고 마지막 p element text color를 orange-400으로 설정하는 예제이다.
{testList.map((item) => (
<p className="first-of-type:text-blue-400 last-of-type:text-orange-400">
Test {item}
</p>
))}
Modifer 이어 붙이기
만약 hover가 발생했을 때 first-of-type인 p element에만 style을 적용하고 싶다면 어떻게 해야할까? 그럴 때는 다음과 같이 modifier를 이어서 적용한다.
{testList.map((item) => (
<p className="hover:first-of-type:text-purple-500">Test {item}</p>
))}
위의 예제처럼 적용하면 오직 첫 번째 p element만 hover가 발생했을 때 text color가 변경된다. responsive breakpoint 역시 위와 같은 방법으로 이어서 적용할 수 있다.
{testList.map((item) => (
<p className="lg:first-of-type:text-purple-500">Test {item}</p>
))}
위의 예제는 viewport가 lg이상 되었을 때 첫 번째 p element에 text color를 적용한다.
Input 상태에 따른 style
required, invalid, disabled과 같은 mofidier를 통해 Input의 상태에 따라 style을 적용할 수 있다.
// input value가 올바른 email 형식이 아니면 red-400 border 적용
<input
type="email"
className="border
focus:outline-none i
nvalid:border-red-400"
/>
// input이 disabled 상태일 때 slate-400 bg color 적용
<input
type="email"
disabled
className="border
focus:outline-none
disabled:bg-slate-400"
/>
// input이 required 상태일 때 green-400 border 적용
<input
type="email"
required
className="border focus:outline-none required:border-green-400"
/>
Placeholder style
input의 placeholder 역시 다음과 같이 간단히 style을 적용할 수 있다. 아래 예제는 placeholder의 text color를 변경하는 예제이다.
<input
type="text"
placeholder="test input"
className="placeholder:text-blue-400"
/>
File input style
만약 file input이 가진 default style을 변경하려면 다음과 같이 style을 적용할 수 있다. file: modifier가 붙지 않은 style은 file이 선택되었을 때 나오는 text에 적용되는 style이고 file: modifier가 붙은 style은 default로 나오는 file upload button에 적용할 style이다.
<input
type="file"
className="text-sm text-gray-500
file:mr-4 file:py-2 file:px-4
file:rounded-full file:border-0
file:bg-blue-50 file:text-blue-700
hover:file:bg-blue-100"
/>
주의할 점은 tailwind가 default로 element의 border를 reset하는 global style은 file input button에는 적용되지 않기에 file input button에 border 관련 style 설정은 직접 선언해 줘야 한다. ( 위의 예제에선 file:border-0를 통해 설정해주고 있다 )
위의 결과는 다음과 같다.

Parent state에 따른 style 적용
만약 parent element에 hover와 같은 action이 발생 했을 때 child elemnt에 특정 style을 적용해야 한다면 group modifier를 통해 style을 적용할 수 있다. 다음 예제를 살펴보자.
<div className="p-5 group">
<h1 className="text-xl group-hover:text-green-500">Title</h1>
</div>
Target parent element에 group class를 설정해주고 style을 적용할 child element에 group-* 형식으로 어떤 action이나 상태가 발생했을 때 어떤 style을 적용할 것인가를 설정한다.
위의 예제에선 group class가 추가된 parent element에 hover가 발생하면 h1 element의 text color가 green-500으로 변경된다.
물론 hover 뿐만 아니라 다른 modifier 역시 적용 가능하다. 아래 예제는 parent element에 hover가 발생했을 때 첫 번째 p element의 text color만 변경하는 예제이다.
<div className="p-5 group">
{testList.map((item) => (
<p className="group-hover:first-of-type:text-purple-500">
Test {item}
</p>
))}
</div>
만약 여러개의 group을 중첩해서 사용해야 하는 상황이라면 group/그룹이름과 같이 group에 특정한 이름을 부여해서 구분할 수 있다.
<div className="p-7 group/container">
{testList.map((item) => (
<div className="p-2 border group/box
group-hover/container:border-blue-400">
<p className="group-hover/box:text-purple-500">
Test {item}
</p>
</div>
))}
</div>
위의 예제에선 제일 상단의 div element group 이름은 container로 설정하고 p element를 감싸고 있는 div element의 group 이름은 box로 설정하였다.
그리고 p element를 감싸고 있는 div는 그 부모 element인 container group div가 hover되었을 때 blue-400 border를 적용하고 p element는 그 부모 element인 box group div가 hover되었을 때 text color를 적용한다.
Peer element의 상태에 따른 style 적용
parent element의 상태뿐만 아니라 peer element의 상태에 따라 style을 적용할 수도 있다. 상태를 파악할 element에 peer utility를 추가하고 다음 element에 peer-required:text-red-500과 같이 peer-상태 형식으로 원하는 style을 적용할 수 있다.
<input type="email" required className="border peer" />
<p className="mt-2 invisible peer-required:visible text-pink-600 text-sm">
Please provide a valid email address.
</p>
위의 예제는 input element가 required일 때 visible utiltiy를 적용하는 예제다.
peer modifier를 사용할 때 주의해야할 점은 peer utility를 적용하는 element는 상태에 따라 다른 style이 적용되는 element 이전에 선언되어 있어야 한다는 점이다. 예를 들어 아래의 예제와 같이 input을 p element 아래로 보내면 peer-required style은 적용되지 않는다.
<p className="mt-2 invisible peer-required:visible text-pink-600 text-sm">
Please provide a valid email address.
</p>
<input type="email" required className="border peer" />
peer도 group과 마찬가지로 고유한 이름을 설정하여 구분할 수 있다.
<input type="email" required className="border peer/email" />
<p className="mt-2 invisible peer-required/email:visible text-pink-600 text-sm">
Please provide a valid email address.
</p>
Parent에서 child style 정하기
대부분에 경우 tailwind class utility는 실제 style을 적용할 element에 직접 적용해 주는 것이 좋지만 가끔 특정 element에 직접 class utility를 지정해주기 어려울 때가 있다. 그럴 때는 다음과 같이 parent element에서 child element style을 정할 수 있다.
<div className="p-7 *:border *:p-3">
{testList.map((item) => (
<p>Test {item}</p>
))}
</div>
위의 예제와 같이 설정해 주면 div안에 존재하는 모든 p tag는 border와 padding이 적용된다.
만약 child element에 parent에서 * modifer로 지정한 child class utilty와 같은 utility가 적용되어 있다면 parent에서 선언된 * modifier가 우선권을 가진다. 예를 들어 아래의 예제에서 p의 border color는 blue가 최종적으로 적용된다.
<div className="p-7 *:border *:border-blue-400">
{testList.map((item) => (
<p className="border-purple-500">Test {item}</p>
))}
</div>
Child element의 상태에 따라 style 적용
group modifier를 통해 parent element의 상태에 따라 child element의 style을 적용했듯이 has-* modifier를 통해 child element 상태에 따라 parent element에 다른 style을 적용할 수 있다.
<div className="p-3 has-[:active]:bg-blue-400">
<button>Test</button>
</div>
위의 예제에서 button element가 active 상태가 되면 parent element에 bg-blue-400 style이 적용된다. 다음과 같이 check box input이 checked가 되었는지에 따라 style을 적용할 수도 있다.
<div className="p-3 has-[:checked]:bg-blue-400">
<input type="checkbox" />
</div>
List item marker style
marker modifier를 통해 List item의 marker에 style을 적용할 수 있다.
<ul className="marker:text-sky-400 list-disc space-y-3">
<li>List 1</li>
<li>List 2</li>
</ul>
Viewport orientation
viewport orientation에 따라 style을 적용하고자 한다면 다음과 같이 orientation modiler를 통해 style을 적용한다. 다음 예제는 viewport가 orientation일 때만 border를 적용하는 예제 코드다.
<div className="portrait:border portrait:border-blue-500">
...
</div>
Support modifier
support modifier를 통해 browser가 특정 기능을 지원할 때만 특정 style을 적용하도록 할 수 있다. 다음 예제는 만약 browser가 grid 속성을 지원하지 않으면 grid를 적용하지 않는다.
<div className="p-2 supports-[display:grid]:grid">
...
</div>
![[ 살펴보기 ] RDB - Relationships](https://cdn.hashnode.com/res/hashnode/image/upload/v1739711556668/48dc9e84-a621-42aa-9c9f-5fc5c436f0ec.jpeg)
![[ 살펴보기 ] MySQL - Data types](https://cdn.hashnode.com/res/hashnode/image/upload/v1739593589113/530f8704-4d27-42c9-a451-bb5c63150b99.jpeg)
![[ 살펴보기 ] TypeORM - Transactions, Migration](https://cdn.hashnode.com/res/hashnode/image/upload/v1739106042581/980b8133-61d4-406a-a026-65be9c28eace.jpeg)
![[ 살펴보기 ] TypeORM - Relations](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666874402/b688bd0b-b6bb-4f43-87d8-c1b46b59f1b7.jpeg)
![[ 살펴보기 ] TypeORM - Basics](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666803591/bef5df17-7dc7-4123-ae55-004d5042df39.jpeg)