# Sass ( SCSS ) 작성법
SCSS와 Sass는 둘 다 CSS의 전처리기로, CSS를 더 쉽게 작성하고 관리할 수 있도록 도와줍니다.
- 문법:
- Sass (Syntactically Awesome Style Sheets): 들여쓰기를 사용하여 CSS와 다르게 보이게 만들어줍니다. 중괄호 {}와 세미콜론 ;을 사용하지 않습니다.
- SCSS (Sassy CSS): CSS와 유사한 문법을 가지고 있습니다. 중괄호 {}와 세미콜론 ;을 사용하여 CSS와 거의 동일한 구조를 가지고 있습니다.
- 호환성:
- SCSS는 CSS와 거의 동일한 문법을 사용하기 때문에 기존 CSS 파일을 쉽게 가져와서 수정할 수 있습니다.
- Sass 는 기존 CSS 파일과 호환성이 떨어질 수 있습니다. 기존 CSS를 Sass 로 변환하기 위해서는 일부 구문을 변경해야 할 수도 있습니다.
- 파일 확장자:
- SCSS 파일은 .scss 확장자를 가지고 있습니다.
- SASS 파일은 .sass 확장자를 가지고 있습니다.
Sass 예)
.header
background-color:pink
color: white
padding: 20px
text-align: center
.nav
ul
list-style-type: none
padding: 0
margin: 0
li
display: inline-block
margin-right: 10px
a
text-decoration: none
color: blue
SCSS예)
.header {
background-color: pink
color: white;
padding: 20px;
text-align: center;
}
.nav {
ul {
list-style-type: none;
padding: 0;
margin: 0;
li {
display: inline-block;
margin-right: 10px;
a {
text-decoration: none;
color: blue;
}
}
}
}
# Sass ( SCSS ) 설치
# vscode 확장프로그램설치
Sass
Live sass compiler
vscode - 메뉴 - 설정
live sass compiler 검색
"liveSassCompile.settings.includeItems": [
"/css/scss/ *.scss"
],
"liveSassCompile.settings.generateMap": false,
"liveSassCompile.settings.formats":[
{
"format": "expanded",
"extensionName": ".css",
"savePath": "~/../css"
}
],
"liveSassCompile.settings.useNewCompiler": false,
"liveSassCompile.settings.autoprefix": [],
"liveSassCompile.settings.watchOnLaunch": true
null : scss/sass 파일이 위치한 폴더에 CSS를 생성한다
/: 제일 상위(root)에서부터 디렉터리를 지정한다
~:파일이 위치한 곳을 기준으로 디렉터리를 지정한다
: expanded
div {
font-size:20px;
color: green;
}
: compact
div { font-size:20px; color: green; }
컴파일이 안될 경우
=> Nodejs
https://nodejs.org/ko/ => LTS 버전 설치
# Sass ( SCSS ) 설치2
node --v
노드 버전 확인
npm i - D sass
-D : devDependencies(개발종속) 현재 프로젝트에만 추가
package.json
{
"scripts": {
"dev": "sass scss:css --watch",
"build": "sass scss:build --style=compressed --no--source-map"
},
"dependencies": {
"-": "^0.0.1",
"D": "^1.0.0",
"sass": "^1.75.0"
}
}
npm run dev
실행
사이트 | |
공식 사이트 | 한글 사이트 |
CSS 전처리기
CSS의 확장된 형태로, CSS 코드 작성을 보다 효율적으로 만들어 주는 도구입니다. 일반적으로 CSS 전처리기는 여러 가지 기능을 제공하여 CSS 코드의 가독성, 유지 보수성, 재사용성을 향상시킵니다. 몇 가지 주요한 CSS 전처리기로는 SCSS(Sass), LESS, Stylus 등이 있습니다.
- 변수 (Variables): 값을 저장하고 재사용할 수 있는 변수를 정의할 수 있습니다. 이를 통해 색상, 글꼴, 여백 등의 값을 중앙에서 관리할 수 있습니다.
- 중첩 (Nesting): 선택자를 중첩하여 보다 가독성이 높은 코드를 작성할 수 있습니다. 이는 HTML의 구조와 일치하여 코드를 이해하기 쉽게 만들어 줍니다.
- 믹스인 (Mixins): 재사용 가능한 코드 블록을 만들어 사용할 수 있습니다. 이를 통해 반복되는 코드를 줄이고 코드의 일관성을 유지할 수 있습니다.
- 확장 (Extend): 한 규칙의 속성을 다른 규칙에 상속할 수 있습니다. 이는 코드의 재사용성을 높이고 반복을 줄여줍니다.
- 조건문 (Conditionals): 조건문을 사용하여 특정 조건에 따라 스타일을 적용할 수 있습니다. 이는 동적인 스타일링을 구현하는 데 유용합니다.
- 반복문 (Loops): 반복문을 사용하여 반복되는 코드를 간편하게 생성할 수 있습니다. 이는 일정한 패턴을 가진 여러 요소에 스타일을 적용할 때 유용합니다.
CSS문법과 유사하지만 중첩, 조건문, 반복문, 변수, 연산등을 편하게 사용할수 있습니다.
중첩 (Nesting): CSS 선택자를 중첩하여 코드를 구조화합니다.
- 문법: 선택자 { 속성: 값; }
주석 (Comments): 코드에 설명을 추가합니다.
변수
믹스인 (Mixins): 재사용 가능한 코드 블록을 생성합니다.
확장 (Extend): 하나의 규칙을 다른 규칙에 확장합니다.
- 문법: @extend 선택자;
- 예시: .success { @extend .message; }
조건문 (Conditionals): 조건문을 사용하여 스타일을 적용합니다.
반복문 (Loops): 반복문을 사용하여 코드를 생성합니다.
- @for, @each, @while 등의 반복문이 있습니다.
import: 다른 SCSS 파일을 가져와서 현재 파일에 포함시킵니다.
- 문법: @import '파일경로';
- 예시: @import 'variables';
01. 중첩(Nesting)
Sass는 중첩 기능을 사용할 수 있습니다.
상위 선택자의 반복을 피하고 좀 더 편리하게 구조를 작성할 수 있습니다.
예시 1) 작성법
html
<h1>예제1</h1>
<div class="parents">
<div class="child1">안녕 SCSS</div>
<div class="child2">컨텐츠</div>
</div>
scss
.parents {
background-color: #999;
.child1 {
color: red;
}
.child2 {
color: blue;
}
}
css
.parents {
background-color: #999;
}
.parents .child1 {
color: red;
}
.parents .child2 {
color: blue;
}
형식
부모요소또는 부모클래스 {
속성 : 값 ;
자식요소 또는 자식클래스 {
속성 : 값 ;
}
}
결과
scss)
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
css)
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
nav a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
실습 1) 작성법 아래 css를 scss로 작성해 보세요
<!-- div.con-box>div.box>p{안녕하세요} -->
<div class="con-box">
<div class="box">
<span>지금은연습중</span>
<p>안녕하세요</p>
</div>
</div>
css
.con-box {
width: 300px;
padding: 20px;
border: 1px solid #000;
}
.con-box .box {
background: pink;
}
.con-box .box span {
font-size: 25px;
font-weight: 700;
}
.con-box .box p {
background: hotpink;
text-indent: 20px;
}
결과
실습 2)
<header id="header">
<div class="inner">
<h1><a href="#"><img src="https://via.placeholder.com/100x50" alt=""></a></h1>
<nav class="nav">
<ul class="gnb">
<li><a href="#">MainMenu1</a></li>
<li><a href="#">MainMenu2</a></li>
<li><a href="#">MainMenu3</a></li>
<li><a href="#">MainMenu4</a></li>
<li><a href="#">MainMenu5</a></li>
</ul>
</nav>
</div>
</header>
결과
scss)
ul > {
li {
list-style-type: none;
}
}
h2 {
+ p {
border-top: 1px solid gray;
}
}
p {
~ {
span {
opacity: 0.8;
}
}
}
css)
ul > li {
list-style-type: none;
}
h2 + p {
border-top: 1px solid gray;
}
p ~ span {
opacity: 0.8;
}
02. 중첩된 속성
font-, margin-, padding-과 같이 동일한 네임 스페이스를 가지는 속성들을 다음과 같이 사용할 수 있습니다.
.con-box {
font: {
weight: 700;
size: 16px;
family: 굴림;
};
margin: {
top: 30px;
left: 10px;
right: 30px;
top: 25px;
};
padding: {
top: 10px;
bottom: 30px;
right: 20px;
};
}
h2 {
font: 30px/50px "굴림체" {
weight:bold;
style:italic;
}
.info-page {
margin: auto {
bottom: 10px;
top: 2px;
}
}
03. Ampersand (상위 선택자 참조)
중첩 안에서 & 키워드는 상위(부모) 선택자를 참조하여 치환합니다.
&선택자
&:가상선택자
&. 클래스
.box {
background-color: #dcdcdc;
display: flex;
// & = .box : 부모 선택자
// &-text = .box-text : 부모 선택자-text
// .box-text
&-text {
font: {
family: '굴림체';
size: 20px;
weight: 700;
}
}
//.box:hover .box-text
&:hover &-text {
color: #fff;
}
}
.con-box {
width: 500px; display: flex;
p {
font-size: 25px;
//.con-box p:nth-child(odd)
&:nth-child(odd) {
background: pink;
}
//.con-box p:nth-child(even)
&:nth-child(even) {
background: yellow;
}
//.con-box p:hover
&:hover {
background: green;
}
}
}
.list {
display: flex;
li {
width: 20px;
//.list li.on
&.on {
background: tomato;
}
//.list li:last-child
&:last-child {
border:1px solid #000
}
}
}
.xi {
&-expand { color:red; }
&-dashboard { color:green; }
&-eye { color:blue; }
&-trash{ color:pink; }
}
.xi-expand { color:red; }
.xi-dashboard { color:green; }
.xi-eye { color:blue; }
.xi-trash{ color:pink; }
04. 최상위로부터 경로 설정
선택자 & {}
.list {
margin: 30px;
li {
width: 300px;
a {
display: block;
text-align: center;
&:hover {
background: pink;
}
// 최상위로 부터 경로 설정
// .wrap .list li a
.wrap & {
background: tomato;
}
}
}
}
scss )
.alert {
&:hover {
font-weight: bold;
}
[dir=rtl] & {
margin-left: 0;
margin-right: 10px;
}
:not(&) {
opacity: 0.8;
}
}
css)
.alert:hover {
font-weight: bold;
}
[dir=rtl] .alert {
margin-left: 0;
margin-right: 10px;
}
:not(.alert) {
opacity: 0.8;
}
scss )
.accordion {
max-width: 600px;
margin: 4rem auto;
width: 90%;
font-family: "Raleway", sans-serif;
background: #f4f4f4;
&__copy {
display: none;
padding: 1rem 1.5rem 2rem 1.5rem;
color: gray;
line-height: 1.6;
font-size: 14px;
font-weight: 500;
&--open {
display: block;
}
}
}
css)
.accordion {
max-width: 600px;
margin: 4rem auto;
width: 90%;
font-family: "Raleway", sans-serif;
background: #f4f4f4;
}
.accordion__copy {
display: none;
padding: 1rem 1.5rem 2rem 1.5rem;
color: gray;
line-height: 1.6;
font-size: 14px;
font-weight: 500;
}
.accordion__copy--open {
display: block;
}
05. @at-root (중첩 벗어나기)
중첩에서 벗어나고 싶을 때 @at-root 키워드를 사용합니다.
중첩 안에서 생성하되 중첩 밖에서 사용하는 경우에 유용합니다.
.con-box {
ul {
display: flex;
li {
margin: 15px;
a {
font-size: 18px;
color:tomato;
// 중첩을 벗어나서 다른 경로를 설정
// #wrap .box
@at-root #wrap .box {
background: pink;
}
}
}
}
}
05. 변수(Variables)
변수 이름 앞에는 항상 $를 붙입니다.
형식
$변수이름 : 속성값 ;
!global (전역 설정) : !global 플래그를 사용하면 변수의 유효범위를 전역(Global)으로 설정
.circle {
$size: 100px;
width: $size;
height: $size;
border-radius: $size * 0.5;
}
$primary: #81899b;
$accent: #302e24;
$warn: #dfa612;
:root {
--primary: #{$primary};
--accent: #{$accent};
--warn: #{$warn};
--consumed-by-js: $primary;
}
$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);
.alert {
border: 1px solid $border-dark;
}
$width: 100px;
.box1 {
background-color: #999;
height: 100px;
width: $width;
border-radius: 20px;
}
.box2 {
background-color: blue;
height: 300px;
width: $width;
border-radius: 20px;
}
$color:tomato;
$size : 50px;
body {
font-size: $size;
}
span {
color:$color;
}
h2 {
$color : skyblue !global;
color:$color;
}
$con1 : "안녕하세요";
$con2 : "SCSS 연습";
p::before {
content:$con1;
font-size: 40px;
}
p::after {
content:$con2;
font-size: 40px;
}
$bg-color: #EEE;
$title-background: #333;
$main-color: #FFF;
.container {
background-color: $bg-color;
padding: 20px;
.title {
background-color: $title-background;
color: $main-color;
text-align: center;
padding: 10px;
}
}
.container-bottom {
background-color: blue;
padding: 50px;
text-align: center;
}
06. #{ } (문자 보간)
#{ }를 이용해서 변수 값을 넣을 수 있습니다.
# { 변수 }
$width: 100px;
$key: width;
.box1 {
background-color: #999;
height: 100px;
#{$key}: $width;
border-radius: 20px;
}
.box2 {
background-color: blue;
height: 300px;
#{$key}: $width;
border-radius: 20px;
}
$color1:pink;
$bot : bottom;
.bg-#{$color1} {
background: $color1;
h2 {
border-#{$bot}: 3px solid #000;
}
}
07. 연산자
산술 연산자 : + , - , * , / , %
단 / 나누기는 단독으로 사용할 수 없으므로 단독일 경우에는 ()로 묶여서 사용해야 함
비교 연산자 : == , != >, < , >= , <=
논리 연산자 : and 그리고 , or 또는 , not 부정
상대적 단위 연산
px : 절대 단위
% , em, vw : calc()
width : calc( 100% - 40px )
- 산술 연산자
$w:100px;
div {
width: 50px + 50px;
width: 100px - 50px;
width: 50px * 2;
width: (50px / 2 );
width: 50px + 50px/2;
width: $w/2;
}
08. 재활용(Mixins)
@mixin과 @include
믹스인은 CSS 규칙과 Sass 문서에서 허용되는 거의 모든 것을 포함할 수 있습니다. 심지어 함수처럼 전달인자를 취할 수도 있습니다.
선언 : @mixin
사용 : @include
@mixin 믹스인이름 {
스타일;
}
선택자 {
@include 믹스인이름
}
@mixin reset-list {
margin: 0;
padding: 0;
list-style: none;
}
@mixin horizontal-list {
@include reset-list;
li {
display: inline-block;
margin: {
left: -2px;
right: 2em;
}
}
}
nav ul {
@include horizontal-list;
}
- 인수( Arguments )
Mixin은 함수처럼 인수를 가질수 있습니다.
@mixin 믹스인이름( $매개변수 ) {
스타일;
}
@include 믹스인이름( 인수 );
@mixin 믹스인이름( $매개변수 : 기본값) {
스타일;
}
@include 믹스인이름( $매개변수 : 인수 );
@mixin rtl($property, $ltr-value, $rtl-value) {
#{$property}: $ltr-value;
[dir=rtl] & {
#{$property}: $rtl-value;
}
}
.sidebar {
@include rtl(float, left, right);
}
@mixin replace-text($image, $x: 50%, $y: 50%) {
text-indent: -99999em;
overflow: hidden;
text-align: left;
background: {
image: $image;
repeat: no-repeat;
position: $x $y;
}
}
.mail-icon {
@include replace-text(url("/images/mail.svg"), 0);
}
@mixin square($size, $radius: 0) {
width: $size;
height: $size;
@if $radius != 0 {
border-radius: $radius;
}
}
.avatar {
@include sq
- 가변인수 : 매개변수 뒤에 ... 붙입니다.
@mixin 믹스인이름( $매개변수...) {
스타일;
}
@include 믹스인이름( 인수, 인수, 인수, 인수);
@mixin order($height, $selectors...) {
@for $i from 0 to length($selectors) {
#{nth($selectors, $i + 1)} {
position: absolute;
height: $height;
margin-top: $i * $height;
}
}
}
@include order(150px, "input.name", "input.address", "input.zip");
@content
@conent가 포함되어 있으면 스타일 블록을 전달할 수 있습니다.
@mixmin 믹스인이름() {
스타일;
@content;
}
@include 믹스인이름() {
스타일;
}
@mixin hover {
&:not([disabled]):hover {
@content;
}
}
.button {
border: 1px solid black;
@include hover {
border-width: 2px;
}
}
css)
.button {
border: 1px solid black;
}
.button:not([disabled]):hover {
border-width: 2px;
}
확장( Extend )
선택자의 확장 기능을 사용할 수 있습니다.
@extend 선택자;
.error {
border: 1px #f00;
background-color: #fdd;
&--serious {
@extend .error;
border-width: 3px;
}
}
.error, .error--serious {
border: 1px #f00;
background-color: #fdd;
}
.error--serious {
border-width: 3px;
}
.error:hover {
background-color: #fee;
}
.error--serious {
@extend .error;
border-width: 3px;
}
.error:hover, .error--serious:hover {
background-color: #fee;
}
.error--serious {
border-width: 3px;
}
함수 ( Functions )
사용자 정의 함수를 사용할수있으며 @return 값을 반환합니다.
@mixin 믹스인이름( $매개변수 ) {
스타일;
}
@include 믹스인이름( 인수 ) ;
@funciton 함수이름( $매개변수 ) {
@return 값
}
함수이름(인수)
@function fibonacci($n) {
$sequence: 0 1;
@for $_ from 1 through $n {
$new: nth($sequence, length($sequence)) + nth($sequence, length($sequence) - 1);
$sequence: append($sequence, $new);
}
@return nth($sequence, length($sequence));
}
.sidebar {
float: left;
margin-left: fibonacci(4) * 1px;
}
@function invert($color, $amount: 100%) {
$inverse: change-color($color, $hue: hue($color) + 180);
@return mix($inverse, $color, $amount);
}
$primary-color: #036;
.header {
background-color: invert($primary-color, 80%);
}
$primary-color: #036;
.banner {
background-color: $primary-color;
color: scale-color($primary-color, $lightness: +40%);
}
09. 조건문 : if문
if() : 조건의 값이 true 이면 표현식 1을 조건의 값이 false이면 표현식 2를 실행합니다.
if( 조건 , 표현식1, 표현식2 )
$rounded-corners: false;
.button {
border: 1px solid black;
border-radius: if($rounded-corners, 5px, null);
}
// @if
@if (조건) {
/* 조건이 참일 때 */
}
// @if @else
@if (조건) {
/* 조건이 참일 때 */
} @else {
/* 조건이 거짓일 때 */
}
// @if @else if
@if (조건1) {
/* 조건1이 참일 때 */
} @else if (조건2) {
/* 조건2가 참일 때 */
} @else {
/* 모두 거짓일 때 */
}
@mixin avatar($size, $circle: false) {
width: $size;
height: $size;
@if $circle {
border-radius: math.div($size, 2);
}
}
.square-av {
@include avatar(100px, $circle: false);
}
.circle-av {
@include avatar(100px, $circle: true);
}
$light-background: #f2ece4;
$light-text: #036;
$dark-background: #6b717f;
$dark-text: #d2e1dd;
@mixin theme-colors($light-theme: true) {
@if $light-theme {
background-color: $light-background;
color: $light-text;
} @else {
background-color: $dark-background;
color: $dark-text;
}
}
.banner {
@include theme-colors($light-theme: true);
body.dark & {
@include theme-colors($light-theme: false);
}
}
@mixin triangle($size, $color, $direction) {
height: 0;
width: 0;
border-color: transparent;
border-style: solid;
border-width: math.div($size, 2);
@if $direction == up {
border-bottom-color: $color;
} @else if $direction == right {
border-left-color: $color;
} @else if $direction == down {
border-top-color: $color;
} @else if $direction == left {
border-right-color: $color;
} @else {
@error "Unknown direction #{$direction}.";
}
}
.next {
@include triangle(5px, black, right);
}
09. 반복문 : for문
@for : 스타일을 반복적으로 출력 for문과 유사합니다.
@for $변수 from 시작값 through 끝값 { } 또는 @for $변수 from 시작값 to 끝값 { }
// through
// 종료 만큼 반복
@for $변수 from 시작 through 종료 {
// 반복 내용
}
// to
// 종료 직전까지 반복
@for $변수 from 시작 to 종료 {
// 반복 내용
}
$base-color: #036;
@for $i from 1 through 3 {
ul:nth-child(3n + #{$i}) {
background-color: lighten($base-color, $i * 5%);
}
}
ul:nth-child(3n+1) {
background-color: #004080;
}
ul:nth-child(3n+2) {
background-color: #004d99;
}
ul:nth-child(3n+3) {
background-color: #0059b3;
}
@each
: 데이터를 반복할때 사용
@each $변수 in 리스트 { }
@each $변수 in 데이터 {
// 반복 내용
}
$sizes: 40px, 50px, 80px;
@each $size in $sizes {
.icon-#{$size} {
font-size: $size;
height: $size;
width: $size;
}
}
css)
.icon-40px {
font-size: 40px;
height: 40px;
width: 40px;
}
.icon-50px {
font-size: 50px;
height: 50px;
width: 50px;
}
.icon-80px {
font-size: 80px;
height: 80px;
width: 80px;
}
SCSS SYNTAX
$icons: ("eye": "\f112", "start": "\f12e", "stop": "\f12f");
@each $name, $glyph in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: "Icon Font";
content: $glyph;
}
}
css)
.icon-eye:before {
display: inline-block;
font-family: "Icon Font";
content: "\f112";
}
.icon-start:before {
display: inline-block;
font-family: "Icon Font";
content: "\f12e";
}
.icon-stop:before {
display: inline-block;
font-family: "Icon Font";
content: "\f12f";
}
$colors: red, green, blue;
@each $color in $colors {
.color-#{$color} {
color: $color;
}
}
.color-red {
color: red;
}
.color-green {
color: green;
}
.color-blue {
color: blue;
}
@while
조건이 false가 될 때까지 반복
@while 조건 {
// 반복 내용
}
@function scale-below($value, $base, $ratio: 1.618) {
@while $value > $base {
$value: math.div($value, $ratio);
}
@return $value;
}
$normal-font-size: 16px;
sup {
font-size: scale-below(20px, 16px);
}
$i: 6;
@while $i > 0 {
.item-#{$i} {
width: 50px * $i;
}
$i: $i - 2;
}
.item-6 {
width: 300px;
}
.item-4 {
width: 200px;
}
.item-2 {
width: 100px;
}
@use
여러개의 스타일시트를 하나로 합칠 수 있습니다.
// scss/_code.scss
code {
padding: .25em;
line-height: 0;
}
// scss/_lists.scss
ul, ol {
text-align: left;
& & {
padding: {
bottom: 0;
left: 0;
}
}
}
// style.scss
@use 'scss/code';
@use 'scss/lists';
css)
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
ex) _main.scss
$primary-color: #336699;
$secondary-color: #993366;
style.scss
@use 'variables';
body {
background-color: variables.$primary-color;
}
.header {
color: variables.$secondary-color;
}
'플러그인 외' 카테고리의 다른 글
[ Markdown ] Markdown 작성법 (0) | 2023.12.14 |
---|---|
[ 플러그인 ] 04. Masonry, isotope (0) | 2023.11.02 |
[ 플러그인 ] 03. AOS (1) | 2023.11.02 |
[ 플러그인 ] 02. swiper, slick, skitter (0) | 2023.11.01 |
[ 플러그인 ] 01. fancybox (1) | 2023.11.01 |