기존에 적용했던 CSS는 태그에 아이디나 클레스를 달아서 사용해야하는 번거로움이있었다.

반응형 웹또한 media screen으로 일일이 정해주고 웹호환이나 사파리 등등의 적용에도 일일이 찾아보고 하는 시간적 비용이 너무 아깝기도 하지만
생산성적인 측면에서 불편함을 많이 느꼇고 어느 css 파일인지 나누는것과 정리가안되서 실수하는 경우가많았다.
어짜피 태그에 아이디를 달아서 지정해주는거라면 그곳에서 그대로 적용하면 보기도 편하고
유지보수도 쉽고 어느위치인지도 파악하기가 쉽다고 느꼇다.
그래서 이전 프로젝트에서 사용했던 tailwind 를 사용하기로 했다.
체계적인 코드관리로 유지보수가 용이하다.
기본설계 및 기능 라이브러리를 제공하여 개발 생산성이 높다
코드에 대한 재사용성이 높다
추상화된 코드 제공을 통해 확장성이 좋다
등의 장점이있지만 간단하게 말해서 쓰기 편하고 빨라서 쓰는게 장점이라 생각한다.

보통 부트스트랩을 많이들어봤지만 이전 프로젝트에서 사용한 경험이 있기떄문에
Tailwind 로 선택했다.
(프로젝트 루트 경로에서 터미널을 열어 수행)
https://tailwindcss.com/docs/guides/vite
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
tailwind.config.js 파일이 생긴다.
이곳에서 내가 원하는 이름으로 커스텀을 할수있다.

커스텀은 이전 프로젝트에서 쓰던것을 재활용했다.
main이라는 이름으로 색을 정해두면 언제든지 주로 사용하는 색을 바꿀수있고 유지보수 또한 편하다는 장점이 있다.
@tailwind base;
@tailwind components;
@tailwind utilities;
이제 tailwind 적용은 끝났다.
기존 PurgeCSS 등에 의존하였던 ‘(네트워크I/O 감소를 위하여) 프로젝트에 사용되지 않은 테일윈드 클래스 제거’ 등이 이제 내장되어 지원됨으로써
클래스네임에 넣을 테일윈드 클래스네임 문자열을 동적으로 생성하여 넣는 경우, 프로젝트 내에 완성된 문자열이 없으므로 테일윈드에 적용되지 않을 수 있음.
예) 다음처럼 사용 시 테일윈드가 “bg-gray-800”을 포함하지 않을 수 있다.
const SampleComponenet = () => {
const myStyleClasses = "bg-gray-" + 800;
return (
<div className={myStyleClasses}>
<h1>뭐시여</h1>
</div>
)
}
또한 앞에적은 클레스이름보다 뒤에적은 클레스이름이 더 우선순위라는점


물론 앞에 !(importent) 붙여 우선순위를 정할수도 있지만 상황에 따라 쓰면 될것같다.

반응형의 경우에도 sm만 클레스명에 붙이면되니 가독성도 좋고 편해졌다.
npm i -D @tailwindcss/line-clamp tailwind-scrollbar-hide
그밖에 CSS지원이 안되는 것도있으니 찾아봐서 적용하면된다.
const defaultColors = require("tailwindcss/colors");
const defaultDropShadows = require("tailwindcss/defaultTheme").dropShadow;
const defaultBoxShadows = require("tailwindcss/defaultTheme").boxShadow;
module.exports = {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
colors: {
main: "#FAC81A",
"main-contra": "#FEFEFE",
sub: "#784FCE",
"sub-contra": "#FFFFFF",
// CART
cart: "#9FC131",
"cart-contra": "#FFFFFF",
// BASIC
basic: "#F0F0F0",
"basic-active": "#F0F0F0",
"basic-contra": "#000000",
// DEFAULT
default: "#d4d4d4",
"default-active": "#e6e6e6",
"default-contra": "#131313",
// PRIMARY
primary: "#1266F1",
"primary-active": "#0c56d0",
"primary-contra": "#FFFFFF",
// SECONDARY
secondary: "#B23CFD",
"secondary-active": "#a316fd",
"secondary-contra": "#FFFFFF",
// SUCCESS
success: "#00B74A",
"success-active": "#00913b",
"success-contra": "#FFFFFF",
// INFO
info: "#39C0ED",
"info-active": "#16b5ea",
"info-contra": "#ffffff",
// WARNING
warning: "#FFA900",
"warning-active": "#d99000",
"warning-contra": "#ffffff",
// DANGER
danger: "#F93154",
"danger-active": "#f80c35",
"danger-contra": "#ffffff",
// LINK
link: "transparent",
"link-active": "transparent",
"link-contra": "#39C0ED",
// LIGHT
light: "#FBFBFB",
"light-active": "#e6e6e6",
"light-contra": "#262626",
// DARK
dark: "#262626",
"dark-active": "#131313",
"dark-contra": "#FBFBFB",
// Back
Back: "#d4d4d4",
"Back-active": "#131313",
"Back-contra": "#FBFBFB",
// Order State
todo: "#FFA900",
"todo-contra": "#ffffff",
doing: "#39C0ED",
"doing-contra": "#ffffff",
// done: "",
// rejected: "",
canceled: "#F93154",
"canceled-contra": "#ffffff",
// noshow: "",
bell: "#FFD700",
"bell-off": "#d3d3d3",
...defaultColors,
},
},
screens: {
sm: "640px",
md: "768px",
lg: "1024px",
xl: "1280px",
"2xl": "1536px",
// smaller
jm: { max: "424px" },
xs: { max: "299px" },
},
boxShadow: {
"t-sm": "0 -1px 1px rgb(0 0 0 / 0.05)",
t: ["0 -1px 2px rgb(0 0 0 / 0.1)", "0 -1px 1px rgb(0 0 0 / 0.06)"],
"t-md": ["0 -4px 3px rgb(0 0 0 / 0.07)", "0 -2px 2px rgb(0 0 0 / 0.06)"],
"t-lg": ["0 -10px 8px rgb(0 0 0 / 0.04)", "0 -4px 3px rgb(0 0 0 / 0.1)"],
"t-xl": [
"0 -20px 13px rgb(0 0 0 / 0.03)",
"0 -8px 5px rgb(0 0 0 / 0.08)",
],
"t-2xl": "0 -25px 25px rgb(0 0 0 / 0.15)",
"t-inner": "inset 0 7px 9px -7px rgba(0,0,0,0.4)",
...defaultBoxShadows,
},
dropShadow: {
"t-sm": "0 -1px 1px rgb(0 0 0 / 0.05)",
t: ["0 -1px 2px rgb(0 0 0 / 0.1)", "0 -1px 1px rgb(0 0 0 / 0.06)"],
"t-md": ["0 -4px 3px rgb(0 0 0 / 0.07)", "0 -2px 2px rgb(0 0 0 / 0.06)"],
"t-lg": ["0 -10px 8px rgb(0 0 0 / 0.04)", "0 -4px 3px rgb(0 0 0 / 0.1)"],
"t-xl": [
"0 -20px 13px rgb(0 0 0 / 0.03)",
"0 -8px 5px rgb(0 0 0 / 0.08)",
],
"t-2xl": "0 -25px 25px rgb(0 0 0 / 0.15)",
...defaultDropShadows,
},
},
plugins: [
require("tailwind-scrollbar-hide"),
require("@tailwindcss/line-clamp"),
function ({ addVariant }) {
addVariant("checked-bg", "& input:checked + *");
addVariant("checked-dot", "& input:checked + * + *");
addVariant("unchecked-bg", "& input + *");
addVariant("unchecked-dot", "& input + * + *");
// === Table Children Selectors ===
// Table section
addVariant("head", "& thead");
addVariant("body", "& tbody");
// Rows
addVariant("all-tr", "& tr");
addVariant("head-tr", "& thead tr");
addVariant("body-tr", "& tbody tr");
// Cells
addVariant("all-td", ["& th", "& td"]);
addVariant("all-td-only", "& td");
addVariant("head-th", "& thead th");
addVariant("head-td", "& thead td");
addVariant("head-td-all", ["& thead th", "& thead td"]);
addVariant("body-th", "& tbody th");
addVariant("body-td", "& tbody td");
addVariant("body-td-all", ["& tbody th", "& tbody td"]);
},
],
};
이렇게 일반화하고 필요할때마다 추가수정하면서 관리할예정이다.