예전에 한 번 sass 정리를 한 적이 있지만 Mixin 같은 기능을 제대로 쓰지 않고 중첩만 쓰기 때문에,, 이번 기회에 다시 정리하여 효율적으로 써보고자 정리를 해본다,,,,
예전에 했던 sass 정리 https://velog.io/@jhyun_k/HTMLCSS%EC%A0%95%EB%A6%AC-11-SCSS
- Sass는 CSS로 컴파일 되는 스타일 시트 확장 언어이며 CSS 전처리기의 하나이다.
- 기술 방식에는
sass
와scss
가 있는데sass
는 우리가 일반적으로 쓰는 css 문법과 다르기 때문에 동일하게 중괄호 문법을 사용하는scss
를 쓴다!
📒 파일분리
- scss 에서는 이렇게 여러 파일을 분리햐여 코드를 작성할 수 있다.
- 파일명 앞에 (언더바)를 붙이면 해당 파일은 컴파일 되지 않는다. 만약 를 붙이지 않을 경우 다 컴파일 되어서 각각의 css 파일이 만들어진다. 하지만 우리에게 필요한건 저 사진상으로 style.scss이므로 나머지에는 _를 붙여줘야 한다.
- Sass에게 이 파일이 main파일의 일부분임을 알려줘서 해당 파일은 css파일로 컴파일하지 않고 내부에서 @import 형태로 작동
- css는 import할 때 파일 URL을 적어줘야 하지만, Sass에서 import할 때는 확장명을 제외하고 파일명만을 사용할 수 있다.
📒 Nesting
- Nesting(중첩)을 사용하면, html의 시각적 계층 방식과 동일하게 CSS를 중첩하여 작성할 수 있다.
- 그러면 유지보수 편해지고 구조화되어 가독성 높아짐 (하지만 너무 과하게 중첩시키면 오히려 보기 어려워져!!!)
//Scss //Scss에서도 HTML처럼 계층구조로 스타일을 적용할 수 있다. nav { background : #C39BD3; padding : 10px; height: 50px; ul { display: flex; list-style : none; justify-content: flex-end; li { color: white; margin-right: 10px; } } }
라는 코드를 css로 쓰려면
nav {background : #C39BD3; padding : 10px; height: 50px;} nav ul {display: flex; list-style : none; justify-content: flex-end;} nav ul li { color: white; margin-right: 10px;}
이렇게 계속 같은 선택자를 반복해서 써야함...(이마짚..) 중첩을 사용하면 최상위 선택자를 한번만 선언하여도 자식 선택자에게 스타일을 적용할 수 있게 되어 코드 반복을 줄이게 된다.
📒 속성 Nesting
scss에서는 무려 속성도 중첩시킬 수 있다..!
//Scss .add-icon { background : { image: url("./assets/arrow-right-solid.svg"); position: center center; repeat: no-repeat; size: 14px 14px; } }
이렇게 background 속성의 하위 속성들을 쓸 때 일일이 background 를 써주지 않아도 되는 것..!
/*CSS*/ .add-icon { background-image: url("./assets/arrow-right-solid.svg"); background-position: center center; background-repeat: no-repeat; background-size: 14px 14px; }
css 였다면 이렇게 일일이 써줘야함.. 축약 속성을 쓰면 되긴 하지만 가끔 안 먹을때는 일일이 쓰게 될 경우도 있단 말이죠..?
📒 & 엠퍼샌드
- "&"는 상위에 있는 부모선택자를 가리킨다.
&
을 이용하여 after, hover 등의 가상요소, 가상클래스, class나 id 셀렉터 등을 참조할 수 있음.
평소에 css에서 가상요소나 가상클래스 사용하려고 하면/*CSS*/ .box:focus{} /* 가상선택자 */ .box:hover{} .box:active{} .box:frist-child{} .box:nth-child(2){} .box::after{} /* 가상요소 */ .box::before{}
이렇게 모든 선택자를 써주고 : 이나 :: 을 해줘야 했음
//Scss .box { &:focus{} // 가상선택자 &:hover{} &:active{} &:first-child{} &:nth-child(2){} &::after{} // 가상요소 &::before{} }
근데 scss에서는
&
를 이용하여 상위선택자 한 번만 쓰면 그 아래에 가상선택자 등등을 써줄 수 있다...! 이건 가끔 쓸 때 마다 늘 유용하다고 생각함....
아래는 scss의 & 을 이용한 예시들//Scss ul { li { &:hover { background: white; cursor: pointer; // 가상요소 } &:last-child { border-bottom: 2px solid black; // 가상클래스 } } } //li 태그의 가상요소와 가상클래스에게 스타일을 적용한 예시 //&을 사용하여 li와 :hover, :last-child를 연결
& 를 응용하면 아래 예시와 같이 공통 클래스 명을 가진 선택자들을 중첩시킬 수 있다.
//Scss .box { &-yellow { background: #ff6347; } &-red { background: #ffd700; } &-green { background: #9acd32; } } //.box라는 이름이 같기 때문에 &를 사용해 중첩구조로 만들 수 있다
이것이 css 였다면
/*CSS*/ .box-yellow { background: #ff6347; } .box-red { background: #ffd700; } .box-green { background: #9acd32; }
이렇게 되는 것이다.
📒 @at-root
@at-root
키워드를 사용하면 중첩에서 벗어날 수 있다.- 중첩에서 벗어나고 싶은 선택자 앞에
@at-root
를 작성한다.- 컴파일된 css 코드에서
@at-root
를 사용한 선택자가 중첩에서 벗어났음을 확인할 수 있다.- 중첩된 선택자에게만 사용할 수 있다.
//Scss .article { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; .article-content { font-size: 14px; opacity: 0.7; @at-root i { opacity: 0.5; } } }
변수를 씀으로써 값을 일일이 고치지 않아도 되고 유지보수가 쉬워질 수 있다. 하지만 충돌할 수도 있기 때문에 적절히 사용해야 한다.
- 변수를 사용하는 기준
- 값이 두 번 이상 반복된다면 미리 변수로 만들어서 값을 기억하지 않고 변수명만을 가지고 스타일을 하기.
- 기존의 값을 다른 값으로 변경해야할 경우, 변수의 값만 변경하면 되기 때문에 값이 수정될 가능성이 있다면 변수 생성을 고려할 수 있다.
📒 변수 생성
$
기호로 변수 만든다.//$변수 : 값 $bgColor : #FFF;
이런 형식
//색상 $red: #ee4444; $black: #222; $bg-color: #3e5e9e; $link-color: red; $p-color: #282A36; //폰트사이즈 $font-p: 13px; $font-h1: 28px; //폰트 $base-font: 'Noto Sans KR', sans-serif; body { background-color : $bg-color; font-size : $font-p; font-family : $base-font; } h1 { font-size: $font-h1; color: $black; }
변수만 지정해두면 같은 값을 여러번 쓰지 않고 변수만 입력해서 사용할 수 있다. 근데 내 경우에는 변수 선언해놓고 변수 자꾸 까먹어서 다시 위로 올라가게 되어서 좀 불편했는데 딱 정해진 컨벤션이 있다면 더 잘 쓸 수 있겠지?
📒 변수 타입
numbers, strings, color, booleans, lists, maps, null이 있다.
- numbers : 1, .82, 20px, 2em 등
- strings : "./images/a.png", bold, left, uppercase 등
- colors : green, #FFF, rgba(255,0,0,.5) 등
- booleans : true, false
- null
- lists
📒 Lists 와 Maps
Lists
- 리스트 = 순서가 있는 값으로, 값마다 인덱스를 가지고 있다.
- lists를 만들려면 lists의 요소들을 쉼표
,
나 공백 또는 일관성이 있는/
로 구분하여 생성하고, 다른 타입의 변수들과 다르게 특수 괄호를 사용하지 않아도 lists로 인식- 빈 lists를 만들 때나 lists에 들어있는 값이 하나 인 경우
[ ]
나( )
를 사용하여 생성한다.- lists에 들어있는 값의 index는 0이 아니라 1부터 시작 (아니 왜요...)
$sizes: 40px, 50px, 80px; $valid-sides: top, bottom, left, right;
list 관련 내장함수
append(list,value,[separator])
,index(list,value)
,nth(list, n)
등이 있다.
append(list,value,[separator])
: lists의 값을 추가하는 함수index(list,value)
: lists의 값에 대한 인덱스를 리턴하는 함수nth(list, n)
: lists의 인덱스에 해당하는 값을 리턴하는 함수// Scss $valid-sides: left, center, right; .screen-box { text-align : nth($valid-sides, 1); }
nth(list, n)
이용해서 lists 의 index 값에 해당하는 값 불러오기Maps
- maps는
( )
괄호 안에키:값
의 형태로 저장하여 사용.- 키와 값을 정의할 때, 키는 고유해야 하지만 키에 해당하는 값은 중복이 가능하다
- 변수를 각각 선언하는 대신, 관련 있는 변수들을 한번에 모아 maps로 만들어서 사용할 수 있습니다.
📒 변수의 scope
변수는 지역변수와 전역변수가 있다. (JS같군...)
지역변수
지역변수는 자기가 선언한 중괄호 { } 안에서만 사용된다 하위단계 중괄호에서도 통함
.info{ $line-normal : 1.34; // 지역변수 font-size : 15px; line-height : $line-normal; text-align : right; span{ line-height : $line-normal; } }
전역변수
전역변수를 가장 윗부분에 정의하면 동일 파일 안에서 어디서든 사용할 수 있다!
//Scss $font-p : 15px; // 전역변수 .main-box{ p { font-size : $font-p; } a { font-size : $font-p; color : blue; text-decoration : none; } }
!global
을 사용하여 local 변수를 global 변수로 만들어 사용할 수도 있지만 권장❌.one { $size : 12px !global; // 권하지 않아요 font-size : $size; }
📒 연산자 (Operator)
사실 ... 이 부분 수업을 제대로 안 들어서 정리할 수 없다. 나중에 추가 예정😥
이것은,, sass 의 꽃 같은 존재이지만 나는 제대로 활용한 적이 없다,, 이번 기회에 확실 정리 가보자고
📒 Mixin 사용하기
@mixin 이름(매개변수) //생성 @include 이름(인수) //사용
요렇게 앞에
@Mixin
을 쓰고 이름을 정해준 후, 중괄호{ }
안에 중복되는 코드를 넣어준다
쓸 때는@include
를 사용하여 스타일 하고자 하는 요소에 포함 시킨다@mixin center-xy{ display: flex; justify-content : center; align-items : center; } .card{ @include center-xy; // 정의한 center-xy mixin을 사용하여 코드 한줄이면 끝! } .aside{ @include center-xy; }
📒 Argument (인수)
파선아실 : 파라미터는 선언, 아규먼트는 실제 값(실행)
@mixin image-style($url, $size, $repeat, $positionX, $positionY) { background-image: url($url); background-size: $size; background-repeat: $repeat; background-position: $positionX $positionY; } //background관련 스타일 코드가 들어있다. //mixin의 인수에 따라 조금씩 다른 스타일링이 가능하다. .profile { @include image-style("./assets/user.jpg", cover, no-repeat, center, center); } .box-one { @include image-style("/images/poster1.svg", cover, no-repeat, 40%, 50%); }
@mixin
이름에 인수 넣어놓고 원할 때@include
로 해당 mixin 가져와서 인수 자리에 값을 넣어준다!// 위에 코드를 가져와서 기본값을 설정해주었다. @mixin image-style($ul, $size, $repeat, $positionX : 50%, $positionY : 50%) { background-image: url($ul); background-size: $size; background-repeat: $repeat; background-position: $positionX $positionY; } .profile { @include image-style("./assets/user.jpg", cover, no-repeat); } // profile과 .box-one은 서로 관계가 없지만, 코드가 중복되기때문에 mixin을 만들어서 // 각 요소에서 사용합니다.
요렇게 해당 매개변수에 값이 들어오지 않을 때 기본값을 지정할 수 있다.
값을 비우거나 안 줄수도 있다. 값 비우기는null
로@mixin pri-button_($width:100px, $height:50px, $radius:10px) { width: $width; height: $height; border-radius: $radius; background-color: aqua; } // 값 비우기 .btn__ { @include pri-button_(100px, null, 20px) } // 중앙값 주지 않기 .btn__ { @include pri-button_(100px, $radius:20px) }
📒 content
@content
를 사용하면 원하는 부분에 스타일을 추가하여 전달할 수 있다// 정의하는 곳에서 @mixin sample{ display: flex; justify-content: center; align-items: center; @content; }
이렇게 정의하고
// 사용하는 곳에서 (추가로 스타일링을 할 수 있음) a { @include sample{ color: white; } }
사용할 때는
@content
자리에 원하는 스타일 추가하면 됨🌱 Mixin 사용하는 다양한 예제
$url : './assets/img'; @mixin thumb($total, $img, $type) { @for $i from 1 through $total { li:nth-child(#{$i}) .thumb { background-image:url(#{$url} + #{$img} + #{$i} + '.' + #{$type}); } } }
@mixin circleBase { display: block; border-radius: 50%; -ms-border-radius: 50%; -webkit-border-radius: 50%; }
@mixin circle($size, $color:null) { $size: unitCheck($size); @include circleBase; width: $size; height: $size; background-color: $color; }
Extend 는 연관있는 코드가 중복될 때 사용
이미 스타일이 작성된 선택자의 클래스를 extend하거나 , %를 사용해서 따로 스타일을 정의한 후 extend하여 원하는 선택자에게 스타일을 적용해 줄 수 있다🤔 Mixin 과 Extend 차이점
- mixin는 (관계 없는) 선택자에서 조금 다른 스타일을 적용할 때 사용
- extend는 관계 있는 선택자들의 동일한 소스코드 적용시 사용
📒 Class 가져오기
기존에 작성한 클래스 내에 있는 코드 가져오기
@extend
에 클래스 명을 함께 적으면, 클래스에 있는 코드 전체가 extend 됨// Scss .profile-user { background-image: url("../assets/user.jpg"); background-size: cover; background-position : 50% 50%; border-radius: 50%; width : 50px; height : 50px; } .comment-user { @extend .profile-user; }
그럼 스타일 두 번 안 써도 쓸 수 있는겨
📒 %placeholder
%
로 선택자를 만듭니다.@extend
를 사용해서 앞서%placeholder
스타일 블럭을 불러오기
그리고 %선택자는 CSS로 컴파일되지 않는다// Scss %base-button { width: 133px; height: 44px; display: flex; justify-content: center; align-items: center; font-size: 14px; border-radius: 10px; } .follow-button { @extend %base-button; background-color: #ffffff; color: #ff375f; border: 3px solid #ff375f; } .message-button { @extend %base-button; background-color: #ff375f; color: white; }
약간 스타일 묶음 느낌으로 볼 수 있을듯,,,
다른 예시// Scss %modal { position: relative; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #fff; border-radius: 6px; } .login-modal { @extend %modal; width: 272px; height: 405px; padding: 10px 20px; } .event-modal { @extend %modal; width: 340px; height: 160px; padding: 18px; }
📒 조건문
조건에 따른 스타일 적용
@if/@else/@elseif
JS 조건문처럼 쓰면 될듯
기본 예제// if문 예시 작성 // Sass 공식문서 // circle이 false면 사각형을, true이면 원형으로 스타일함 @mixin avatar($size, $circle: false) { width: $size; height: $size; @if $circle { border-radius: $size / 2; } } .square-av { @include avatar(100px, $circle: false); } .circle-av { @include avatar(100px, $circle: true); }
circle 이 false 이면 사각형, true 이면 원이니까 .circle-av 에는 border-radius 속성도 적용된다.
@use "sass:math"; $one: 10px; $two: 100px; @mixin avatar($size, $circle: false) { width: $size; height: $size; background-color: red; @if $circle { // border-radius: $size / 2; // step 1 // border-radius: ($size / 2) + px; // step 2 // border-radius: ($size / 2) + "px"; // 문자열 "00px"로 들어감 \ // 시스템 권고사항 // math.div($size, 2) or calc($size / 2) // border-radius: math.div($size, 2); } @else { border-radius: 2px; } } .one { @include avatar(10px, true) } .two { @include avatar(10, true) } .three{ @include avatar(10px, false) } .four{ @include avatar(10px) } .five{ @include avatar(10px, 10 > 100) } .six { @include avatar(10px, $one > $two) }
이렇게 다양하게 쓸 수 있다.
📒 반복문
@for
: 정의한 횟수만큼 코드 반복for ($변수) from (시작) through(끝){ // 반복할 내용 }
@for $i from 1 through 5 { .photo-box:nth-child(#{$i}) { background-image: url("../assets/phoster#{$i}.png"); } } 이나 @for $jihyun from 1 through 3 { .photo-box:nth-child(#{$jihyun}){ background-image: url('../assets/poster#{$jihyun.png'); } }
@for $jihyun from 1 through 12 { .profile-#{$jihyun}{ background-color: red; font-size: #{$jihyun * 10}px; } }
이렇게 사용가능
🌱
@for
문에서through
와to
의 차이
through
는 마지막 숫자를 포함하고to
는 마지막 숫자를 포함하지 않는다.
@each
lists나 맵의 각각의 요소마다 코드를 실행해서 스타일을 적용할 수 있게 합니다.
기본형@each ($변수) in (리스트나 맵){ // 반복할 내용 }
// Sass - each문 // color-palette 리스트에 들어있는 색상을 each문을 사용하여 background에 색상값을 넣어준다. $color-palette: #dad5d2 #3a3532 #375945 #5b8767 #a6c198 #dbdfc8; @each $color in $color-palette { $i: index($color-palette, $color); //index는 list의 내장함수 .color-circle:nth-child(#{$i}) { background: $color; width: 20px; height: 20px; border-radius: 50%; } }
@while
특정 조건에 충족될 때까지 코드를 무한 반복하며, 조건을 만날 때 while문을 빠져나온다.
기본형@while 조건 { // 반복할 내용 }
// sass 참고서의 예제 // $hojun: 5; // @while $hojun > 1 { // $hojun: $hojun - 1; // .content-#{$hojun} { // width: 100px; // height: 100px; // background-color: red; // } // // 쉬운 예제 $jihyun : 10; @while $jihyun > 1 { $jihyun : $jihyun - 2; .content-#{$jihyun}{ width: 100px; height: 100px; background: red; } }
📒 function
@function
키워드를 사용하여 함수를 생성하고 함수이름( ) 형태로 함수를 호출하고 실행한다.- 함수 안에서는
@return
이용해 값을 반환🌱 Mixin 과 function 차이
- mixin은 스타일 코드를 반환하고
- function은
@return
키워드를 사용해서 값 자체를 반환한다기본형
@function 함수이름($매개변수) { // 실행 코드 @return 값 }
@function sigma($number){ $result : 0; @for $i from 1 to $number { $result : $result + $i } @return $result; } .one{ width: sigma(11)px; }
오늘 배우신 거 엄청 깔끔하게 정리하셨네요! 복습할 때 이 글 보겠습니다 ㅎㅎ