다음에 대해서 정리해보려 한다.
1. scss를 통한 button design - 1편
2. 로그인 페이지 디자인 - 2편
3. 기타 쓸모있는 기능 - 2편
우선 밑바탕이 되었던 코드와 배경 지식은 아래와 같다.
그리고 이건 내 코드 authentification-nodejs-react
솔직히 기반 코드 바탕으로 웹 페이지를 만들었다. 따라서 내가 작업한 부분은 창작이라기보다 활용과 이해 및 해석에 가깝다. (부족한 나의 실력은 여전히)
그럼에도 잘 정리하여 누군가는 나만큼 고생하지 않기를 바라며 글을 적는다.
📸
부족한 첫 화면
Sass (Syntactically Awesome Style Sheets)는 CSS pre-processor 로서, 복잡한 작업을 쉽게 할 수 있게 해주고, 코드의 재활용성을 높여줄 뿐 만 아니라, 코드의 가독성을 높여주어 유지 보수를 쉽게 해줍니다.
Scss는 비슷하지만, Sass의 모든 기능을 지원하고 문법이 조금 다른 녀석
@velopert 님 및 블로그 에 글을 정리한 것이다. 내 느낌대로 다시 정리하자면,
정적인 css와 다르게 변수 선언, 조건문, 반복문, 연산 등과 같은 동적인 기능 및 문법을 가진 코드를 적어 스타일링을 하는 느낌
코드로 살펴보면
// Javascript처럼 이런 주석도 가능, 컴파일되지 않는 주석
/* 기존 css 주석과 같은 이것은 컴파일되는 주석 */
// 변수 선언
$font-stack: Helvetica, sans-serif;
body {
font: 100% $font-stack;
}
// mixin 만들기 (재사용되는 스타일 블록을 함수처럼 사용 할 수 있음)
@mixin square($size) {
width: $calculated;
height: $calculated;
}
.Component {
display: flex;
.box {
background: red;
&.red { // & 는 상위 선택자 참조
background: $red;
@include square(1); // mixin 사용
}
}
}
// 조건 및 연산
$width: 90px - 30px;
div {
@if not ($width > 100px) {
height: 300px;
}
}
// 가져오기
@import "hello.css";
@import "http://hello.com/hello";
@import url(hello);
@import "hello" screen;
추가로 파일 분할 및 재활용 기능 등 정말 자바, 파이썬 하듯이 코드를 작성한다.
그렇다면, 내 코드에서 block design을 위한 scss 처리는 어떻게 되어 있을까?
우선 기본적으로 버튼 디자인이 scss로 어떻게 이루어져 있는지 말해보려 한다. 아래 사진에서 소셜 로그인 버튼 과 Duplicated 버튼 의 코드를 예시로 설명하려 한다.
/* 소셜 로그인 버튼 코드 */
// 여러 가지 생략하고 생략한 코드
<div className="btn-wrapper text-center">
<Button
className="btn-neutral btn-icon"
color="default"
href="#pablo"
onClick={e => e.preventDefault()}
>
<span className="btn-inner--icon">
<img/>
</span>
<span className="btn-inner--text">Github</span>
</div>
className에 btn
, btn-neutral
, text-center
과 같은 이름을 붙여 디자인이 되어있는 것을 볼 수 있다.
이렇게 className이 정의되어 있는, scss 구성 및 코드를 설명해본다.
/* Scss 코드 구성 */
└── scss
└── bootstrap
├── mixins
└── ...
├── utilities
└── ...
├── _buttons.scss // 1번 녀석
└── ...
├── core
├── buttons
└── _buttons.scss // 2번 녀석
└── ...
├── custom
├── _buttons.scss // 3번 녀석
└── ...
├── react
└── ...
└── argon-dashboard-react.scss
위와 같이 버튼에 관한 scss 파일은 세 개이다. (사실 더 많더라 @import 되어 있는 것만 설명) argon-dashboard-react.scss
에서 scss 폴더 내에 구성 요소들을 @import
하여 쓰는데, btn
의 경우 2번을 제외한 1번 3번이 @import
되어 사용되고 있다.
하지만,
실제로 버튼에 적용된 디자인은 1번과 2번이다. 왜냐하면 3번에서 2번을 @import
하고 있기 때문이다.
즉, 가져다 쓰는 것도 참 힘들다. 정말 멋들어지게 짜놓으셨다.
/* bootstrap 내 _buttons.scss */
// General styles
.btn {
position: relative;
text-transform: $btn-text-transform;
transition: $transition-base;
letter-spacing: $btn-letter-spacing;
font-size: $input-btn-font-size;
will-change: transform;
&:hover {
@include box-shadow($btn-hover-box-shadow);
transform: translateY($btn-hover-translate-y);
}
&:not(:last-child) {
margin-right: .5rem;
}
...
}
// Remove translateY and margin animation when btn is included in a btn-group or input-group
.btn-group,
.input-group {
.btn {
margin-right: 0;
transform: translateY(0);
}
}
// Size variations
.btn-sm {
font-size: $input-btn-font-size-sm;
}
.btn-lg {
font-size: $input-btn-font-size-lg;
}
// Some quick fixes (to revise)
// Fixes
[class*="btn-outline-"] {
border-width: 1px;
}
.btn-neutral {
color: theme-color("primary");
}
코드를 살펴보면, scss로써 변수, 연산, 상위 참조자 하위 등 여러 가지 기능이 쓰였다.
className 내에 text-center(소셜 로그인 버튼), my-4(Duplicated 버튼) 과 같은 명시를 해주면 형용사처럼 효과가 적용되는데, 이는 utilities로써 표현되는 것이다.
/* 관련 코드 위치 */
─── scss
└── bootstrap
└── utilities
└── _spacing.scss
/* _spacing.scss */
// Margin and Padding
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
@each $prop, $abbrev in (margin: m, padding: p) {
@each $size, $length in $spacers {
.#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }
.#{$abbrev}t#{$infix}-#{$size},
.#{$abbrev}y#{$infix}-#{$size} {
#{$prop}-top: $length !important;
}
.#{$abbrev}r#{$infix}-#{$size},
.#{$abbrev}x#{$infix}-#{$size} {
#{$prop}-right: $length !important;
}
.#{$abbrev}b#{$infix}-#{$size},
.#{$abbrev}y#{$infix}-#{$size} {
#{$prop}-bottom: $length !important;
}
.#{$abbrev}l#{$infix}-#{$size},
.#{$abbrev}x#{$infix}-#{$size} {
#{$prop}-left: $length !important;
}
}
}
// Some special margin utils
.m#{$infix}-auto { margin: auto !important; }
.mt#{$infix}-auto,
.my#{$infix}-auto {
margin-top: auto !important;
}
.mr#{$infix}-auto,
.mx#{$infix}-auto {
margin-right: auto !important;
}
.mb#{$infix}-auto,
.my#{$infix}-auto {
margin-bottom: auto !important;
}
.ml#{$infix}-auto,
.mx#{$infix}-auto {
margin-left: auto !important;
}
}
}
사실 나도 이런 코드를 작성할 만큼 문법이나 자세한 기능에 대해서 잘 모른다. 그저 쓸 뿐... 예쁘고 멋드러지게 잘 짜놓으셨다...
위 코드를 살펴보면, mt-1의 경우,
.#{$abbrev}t#{$infix}-#{$size} {
#{$prop}-top: $length !important;
}
이러한 정의를 통해, (정확하지는 않지만) abbrev
로 m
(margin)을 받고, infix
는 존재하지 않고, size
는 1
로 받아서, margin-top
을 결정하게 된다.
1
은 scss 내 bootstrap 내 _variables.scc
내에 다음과 같이 표현되어 있다.
/* _variables.scc */
// Spacing
//
// Control the default styling of most Bootstrap elements by modifying these
// variables. Mostly focused on spacing.
// You can add more entries to the $spacers map, should you need more variation.
$spacer: 1rem !default;
$spacers: () !default;
// stylelint-disable-next-line scss/dollar-variable-default
$spacers: map-merge(
(
0: 0,
1: ($spacer * .25),
2: ($spacer * .5),
3: $spacer,
4: ($spacer * 1.5),
5: ($spacer * 3)
),
$spacers
);
느낌 상 뭔가 bootstrap을 정리한 것 같기도 하고, 그렇다.
적다보니 점점 길어졌다. 사실 더 길게 쓰려 했지만, 지쳐버려서 이 정도로 마무리하고 2편으로 다시 적어보려 한다. 쉽지 않다.
🙋♂️