우리는 HTML에 스타일을 주기 위해 css를 사용한다.
그러나 수많은 id, class, 선택자 등을 사용하게 되면 css 파일이 굉장히 보기 어려워진다.
sass는 css 코드를 HTML과 유사한 구조로 작성할 수 있는 전처리기이다.
덕분에 css 코드를 분석하는데 아주 유용하다.
scss는 sass에서 나온 문법이며 코드를 작성하는 규칙이 보다 익숙해 sass보다 scss를 사용하는 것을 권장한다.
=> sass는 중괄호 및 세미콜론이 없지만 scss는 있다.
=> 따라서 scss가 한 눈에 구조를 파악하는데 더욱 익숙하다고 할 수 있다.
.list
width: 100px
float: left
li
color: red
background: url("./image.jpg")
&:last-child
margin-right: -10px
.list {
width: 100px;
float: left;
li {
color: red;
background: url("./image.jpg");
&:last-child {
margin-right: -10px;
}
}
}
$npm i sass
앞서 말했듯이 HTML 구조와 유사한 구조로 스타일 시트를 작성하는 것을 말한다.
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
display: inline-block;
}
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
[$변수명 : 값] 형태로 변수를 지정하여 사용할 수 있다.
$primary-color: #333;
body {
border: 1px solid black;
color: $primary-color;
}
.inverse {
background-color: $primary-color;
color: white;
}
Nesting 내부에서 & 선택자는 부모 선택자로 치환된다.
아래 예시처럼 button { &:hover }를 사용하면 button:hover와 같은 의미가 된다.
button {
width: 200px;
height: 50px;
&:hover {
width: 400px;
height: 100px;
}
}
/* Compile to CSS */
button {
width: 200px;
height: 50px;
}
button:hover {
width: 400px;
height: 100px;
}
mixin은 함수라고 생각하면 편하다.
mixin 블록 안에 css 코드를 작성하면 해당 mixin을 호출하는 순간 블록 내부 스타일이 적용된다.
@mixin flexCenter {
display: flex;
justify-content: center;
align-items: center;
}
.info {
@include flexCenter;
}
함수와 마찬가지로 매개변수를 넣을 수 있다.
인자로 null을 보내면 값 설정을 하지 않을 수도 있다.
@mixin flexSort($justify, $alignItems) {
display: flex;
justify-content: $justify;
align-items: $alignItems;
}
.info {
@include flexSort('space-between', 'center');
}
.feed {
@include flexSort('space-around', 'center');
}
이번엔 벨로퍼트님 게시글을 참고하여 버튼 만들기 실습을 해볼 예정이다.
참조 : https://react.vlpt.us/styling/01-sass.html
먼저 trusy 한 값의 이름을 className으로 그대로 들어가게 하고 falsy 값의 이름은 들어가지 않게 하는
classnames << 라이브러리를 먼저 설치한다.
npm i classnames
사용법은 대강 아래와 같다.
import classNames from "classnames";
classNames("one", { two: true, three: false, four: true }); // one two four
자 다시 본론으로 돌아와서,,
버튼에 이것 저것 props와 해당 props를 이용한 스타일링을 진행할 예정이다.
import "./App.css";
import Button from "./components/Button";
function App() {
return (
<>
<Button size="small" color="blue">
Button
</Button>
<Button size="large" color="red">
Button
</Button>
<Button outline>Button</Button>
</>
);
}
export default App;
import classNames from "classnames";
import React from "react";
import "./Button.scss";
const Button = ({ children, size, color, outline }) => {
return (
<button className={classNames("Button", size, color, { outline })}>
Button
</button>
);
};
Button.defaultProps = {
size: "medium",
color: "black",
};
export default Button;
$blue: rgb(63, 149, 241);
$red: rgb(245, 71, 19);
$black: rgb(46, 44, 44);
@mixin button-color($color) {
background: $color;
&:hover {
background: lighten($color, 10%);
}
&:active {
background: darken($color, 10%);
}
&.outline {
color: $color;
background: none;
border: 1px solid $color;
&:hover {
background: $color;
color: white;
}
}
}
.Button {
display: inline-flex;
color: white;
font-weight: bold;
outline: none;
border-radius: 4px;
border: none;
cursor: pointer;
height: 2.25rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1rem;
&.large {
height: 3rem;
font-size: 1.25rem;
}
&.medium {
height: 2.25rem;
font-size: 1rem;
}
&.small {
height: 1.75rem;
font-size: 0.875rem;
}
&.blue {
@include button-color($blue);
}
&.black {
@include button-color($black);
}
&.red {
@include button-color($red);
}
}
먼저 App.js에서 size="small", color="blue" 속성을 가진 버튼 컴포넌트를 생성했다.
Button.js를 보면 classnames 라이브러리를 사용해 "Button" 클래스명과 인자로 전달 받은 size, color 항목을 가지고 css 스타일링을 진행한다.
마지막으로 Button.scss에서는 [$blue, $red, $black] 각각 color가 지정된 세 변수를 정의하고
@mixin을 통해 전달 받은 색상으로 버튼을 스타일링한다.
color 뿐만 아니라 Button 하위에 있는 [&.large, &.medium, &.small]을 설정하여 각 사이즈에 대응하는 버튼을 스탕일링 하였다.
마지막으로 outline이라는 속성을 통해 테두리만 존재하는 버튼이 생성되었다.
이 때 Button.js에서 인자로 전달하는 {outline}의 값은 trusy, falsy를 판단하여
trusy 값일 경우 "outline" 이라는 텍스트 값을 scss에 전달한다.
(참고 : &.large는 Button.large와 같다.)