개발 공부

[Front-end] React 스타일링

jong9810 2023. 10. 21. 01:05

CSS

1. CSS란?

CSS는 Cascading Style Sheets의 약자로써 스타일링을 위한 일종의 언어라고 생각하면 됩니다. CSS에는 여러가지 스타일이 정의되어 있는데 한 번에 여러 스타일이 적용될 경우에 스타일 충돌을 막기 위해 계단식으로 스타일이 적용되는 규칙을 가지고 있습니다.

 

엘리먼트에 스타일이 적용되는 규칙을 selector라고 부릅니다. 단어 그대로 해석하면 선택자라고 할 수 있는데 스타일을 어떤 엘리먼트에 적용할지를 선택하게 해주는 것입니다. CSS는 크게 선택자와 실제 스타일로 이루어져 있습니다.

2. CSS 문법과 선택자

선택자를 먼저 쓰고 이후에 적용할 스타일을 중괄호 안에 세미콜론(;)으로 구분하여 하나씩 기술합니다. 선택자에는 해당 스타일이 적용될 .HTML 엘리먼트를 넣게 됩니다. HTML 태그를 직접 넣거나 다른 조건들을 조합하여 선택자를 작성할 수 있습니다. 선택자 다음에는 중괄호 안에 적용할 스타일을 선언하게 됩니다. 각 스타일은 CSS 속성과 값으로 이뤄진 키-값 쌍이며 CSS 속성의 이름과 값을 콜론(:)으로 구분합니다. 그리고 중괄호로 묶여있는 하나의 스타일 블록에는 스타일이 여러 개 들어갈 수 있는데 여기에서 각 스타일은 세미콜론(;)으로 구분합니다.

 

선택자 종류는 다음과 같이 6가지가 있습니다.

  • 엘리먼트 선택자 : HTML 태그의 이름을 선택합니다.
  • id 선택자(#) : HTML 태그의 id 속성을 이용하여 선택하는 형태이며 샤프(#) 뒤에 아이디를 넣어 사용합니다(고유함).
  • 클래스 선택자(.) : 여러 개의 엘리먼트를 분류하기 위해서 사용하고, 점(.) 뒤에 클래스명을 넣어서 사용합니다.
  • 전체 선택자(*) : 전체 엘리먼트에 적용하기 위한 선택자이며 별표(*)를 사용합니다.
  • 그룹 선택자(,) : 여러가지 선택자를 그룹으로 묶어 하나의 스타일을 적용하기 위해 사용하는 선택자로 콤마(,)를 사용합니다.
  • 상태와 관련된 선택자 : 여기에서 상태라는 것은 마우스 커서가 엘리먼트 위에 올라오거나 엘리먼트가 활성화되어 있는 경우 등을 의미합니다. 대표적으로 :hover, :active, :focus, :checked, :first-child, :last-child 등이 있습니다.

3. 레이아웃과 관련된 속성

웹사이트에서 레이아웃은 화면에 엘리먼트들을 어떻게 배치할 것인지를 의미합니다. 그래서 레이아웃과 관련된 CSS 속성들은 화면상의 배치와 관련이 있다고 생각하면 됩니다.

 

레이아웃과 관련해서 가장 중요한 속성은 display입니다. display 속성은 엘리먼트를 어떻게 표시할지에 관한 속성입니다. 모든 엘리먼트는 그 종류에 따라서 기본적으로 정해진 display 속성값을 갖고 있습니다. 대부분의 엘리먼트는 블록(block) 또는 인라인(inline) 값을 가집니다. display 속성의 값으로는 굉장히 많은 종류가 있는데 대표적으로 아래 코드에 나온 값들이 가장 많이 사용됩니다.

div {
	display: none | block | inline | flex;
}
  • display: none;은 엘리먼트를 화면에서 숨기기 위해 사용합니다. 엘리먼트가 삭제되는 것이 아니라 존재하긴 하지만 화면에 보이지 않는 것이기 때문에 자바스크립트 코드를 넣을 때 주로 사용됩니다.
  • display: block;은 블록 단위로 엘리먼트를 배치하는 것인데 블록 단위라는 것은 엘리먼트가 새로운 줄에서 시작하여 위치한 곳 전체의 sidth를 차지한다는 것을 의미합니다.
  • display: inline;은 말 그대로 엘리먼트를 라인 안에 넣는 것입니다. 이 속성을 사용하게 되면 모든 width, height과 관련된 속성들은 효과가 없어집니다.
  • display: flex;는 엘리먼트를 블록 레벨의 플렉스 컨테이너로 표시하는 것입니다. 컨테이너이기 때문에 내부에 다른 엘리먼트들을 포함한다고 생각하면 됩니다.

다음으로는 visibility입니다. visibility 속성은 엘리먼트를 화면에 보여주거나 감추기 위해 사용하는 속성입니다. 대표적으로 visible과 hidden, 이 두 가지 값을 가장 많이 쓰며 아래 코드처럼 사용합니다.

div {
	visibility: visible | hidden;
}
  • visibility: visible;은 엘리먼트를 화면에 보이게 하는 것입니다.
  • visibility: hidden;은 화면에서 안 보이게 감추는 것입니다. 엘리먼트를 안 보이게만 하는 것이고 화면에서의 영역은 그대로 차지한다는 점을 주의해야 합니다.

다음 CSS 속성은 position입니다. position 속성은 엘리먼트를 어떻게 위치시킬 것인지를 정의하기 위해서 사용합니다.

div {
	position: static | fixed | relative | absolute;
}
  • static은 기본값으로 엘리먼트를 원래의 순서대로 위치시킵니다.
  • fixed는 엘리먼트를 브라우저 "window에" 상대적으로 위치시킵니다.
  • relative는 엘리먼트를 "보통의 위치에" 상대적으로 위치시킵니다. left, top, right, bottom 속성을 추가하면 엘리먼트의 위치를 조정할 수 있습니다.
  • absolute는 엘리먼트를 절대 위체이 위치시키는데 이 때 기준은 첫 번째 상위 엘리먼트가 됩니다.

다음 CSS 속성은 엘리먼트의 가로, 세로 길이와 관련된 속성들입니다. 대표적으로 width, height, min-width, min-height, max-width, max-height가 있으며 값으로 보통 실제 픽셀 값을 넣거나 상대값인 퍼센트(%)를 사용합니다. 또한 px 단위가 아닌 em, rem 등의 단위도 사용할 수 있습니다.

 

각 속성은 단어 그대로 가로 길이, 세로 길이, 최소 가로 길이, 최소 세로 길이, 최대 가로 길이, 최대 세로 길이를 의미합니다. 값으로 auto를 사용하면 브라우저에서 길이를 계산하며, 실제 값을 사용하면 해당 값만큼의 길이를 가지게 됩니다.

4. 플렉스박스

플렉스박스는 레이아웃에서 가장 많이 쓰이고 중요한 속성입니다. 플렉스박스는 기존 CSS의 레이아웃 사용의 불편한 부분을 개선하기 위해 등장했습니다. 

 

플렉스박스는 크게 컨테이너와 아이템으로 구성됩니다. display: flex;를 사용하면 엘리먼트가 플렉스 컨테이너가 된다고 설명했는데 이것이 바로 플렉스박스의 컨테이너입니다. 그리고 플렉스 컨테이너는 내부에 여러 개의 엘리먼트를 포함할 수 있는데 컨테이너에 포함되는 엘리먼트들이 바로 플렉스박스의 아이템입니다. 

 

컨테이너 안에 여러 개의 아이템이 존재할 경우 컨테이너에 들어있는 플렉스와 관련된 CSS 속성은 이 아이템들을 어떤 방향과 어떤 순서로 배치할 것인지를 정의하게 됩니다. 아래 코드는 자주 사용되는 플렉스 관련 CSS 속성들입니다.

div {
	display: flex;
    flex-direction: row | column | row-reverse | column-reverse;
    align-items: stretch | flex-start | center | flex-end | baseline;
    justify-content: flex-start | center | flex-end | space-between | space-around;
}
  1. flex-direction : 아이템들이 어떤 방향으로 배치될 것인지를 지정.
    • row : 기본값이며 아이템을 행을 따라 가로 순서대로 왼쪽부터 배치합니다.
    • column : 아이템을 열을 따라 세로 순서대로 위쪽부터 배치합니다.
    • row-reverse : 아이템을 행의 역방향으로 오른쪽부터 배치합니다.
    • column-reverse : 아이템을 열의 역방향으로 아래쪽부터 배치합니다.
  2. align-items : 컨테이너 내에서 아이템을 어떻게 정렬할 것인지를 지정(cross-axis 기준).
    • stretch : 기본값으로써 아이템을 늘려서 컨테이너를 가득 채웁니다.
    • flex-start : cross-axis의 시작 지점으로 아이템을 정렬합니다.
    • center : cross-axis의 중앙으로 아이템을 정렬합니다.
    • flex-end : cross-axis의 끝 지점으로 아이템을 정렬합니다.
    • baseline : 아이템을 baseline 기준으로 정렬합니다.
  3. justify-content : 컨테이너 내에서 아이템들을 어떻게 나란히 맞출 것인지를 지정 (main-axis 기준) .
    • flex-start : main-axis의 시작 지점으로 아이템을 맞춥니다.
    • center : main-axis의 중앙으로 아이템을 맞춥니다.
    • flex-end : main-axis의 끝 지점으로 아이템을 맞춥니다.
    • space-between : main-axis를 기준으로 첫 아이템은 시작 지점에 맞추고 마지막 아이템은 끝 지점에 맞추며, 중간에 있는 아이템들 사이의 간격이 일정하게 되도록 맞춥니다.
    • space-around : main-axis를 기준으로 각 아이템의 주변 간격을 동일하게 맞춥니다. 여기서 주변의 의미는 아이템의 시작과 끝을 의미합니다.

flex-direction으로 지정된 방향을 main-axis라고 부르고 main-axis를 수직으로 가로지르는 방향의 축을 cross-axis라고 부릅니다. 

5. 폰트와 관련된 속성

div {
	font-family: "사용할 글꼴 이름", <일반적인 글꼴 분류>;
    font-size: value;
    font-weight: normal | bold;
    font-style: normal | italic | oblique;
}
  1. font-family : 어떤 글꼴을 사용할 것인지를 결정하는 속성.
    • 일반적인 글꼴 분류 : serif, sans-serif, monospace, cursive, fantasy 등
  2. font-size : 글꼴의 크기를 지정하는 속성.
    • px, em, rem, vw 등의 단위를 사용할 수 있습니다(1em은 16px).
  3. font-weight : 글꼴의 두께를 지정하는 속성.
    • normal, bold, 100~900 사이의 100 단위 숫자 등을 값으로 사용할 수 있습니다(숫자가 클수록 두꺼운 글씨).
  4. font-style : 글꼴의 스타일을 지정하기 위한 속성.
    • normal : 일반적인 글자의 형태를 의미.
    • italic : 글자가 기울어진 형태로 나타남(기울어진 형태의 글자를 디자인해서 만든 것, italic 지원 여부 확인 후 사요해야 함).
    • oblique : 글자가 비스듬한 형태로 나타남(일반적인 글자를 기울임).

6. 많이 사용하는 기타 속성

  1. background-color : 엘리먼트의 배경색을 지정하는 속성.
    • 16진수 컬러값 : #ff0000
    • 투명도를 가진 16진수 컬러 값 : #ff000055
    • RGB 컬러 값 : rgb(255, 0, 0)
    • RGBA 컬러 값 : rgba(255, 0, 0, 0.5)
    • HSL 컬러 값 : hsl(120, 100%, 25%)
    • HSLA 컬러 값 : hsla(120, 100%, 50%, 0.3)
    • 미리 정의된 색상의 이름 : RED
    • currentcolor 키워드 : 현재 지정된 색상 값을 사용
    • transparent : 배경색을 투명하게 만듦
  2. border : 테두리 스타일을 지정하는 속성.
    • border-width, border-style, border-color의 세 가지 속성을 축약시켜서 한 번에 사용할 수 있게 만든 것이다.
    • ex) border: 2px solid black;

styled-components

style-components는 CSS 문법을 그대로 사용하면서 결과물을 스타일링된 컴포넌트 형태로 만들어주는 오픈소스 라이브러리입니다. 컴포넌트 개념을 사용하기 때문에 리액트와 굉장히 궁합이 잘 맞습니다.

1. styled-components 설치하기

// npm을 사용하는 경우
npm install --save styled-components

// yarn을 사용하는 경우
yarn add styled-components

2. styled-components 기본 사용법

styled-components는 태그드 템플릿 리터럴을 사용하여 구성 요소의 스타일을 지정합니다. 템플릿 리터럴은 자바스크립트에서 제공하는 문법 중 하나입니다. 프로그래밍에서 리터럴은 소스코드의 고정된 값을 의미합니다. 흔히 상수와 헷갈려하는 경우가 있는데 둘은 다른 개념입니다. 

// number는 변수(Variable)이고, 20은 정수 리터럴(Integer Literal)입니다.
const number = 20;

// 문자열 리터럴(String Literal)
const str = 'Hello';

// 배열 리터럴(Array Literal)
const arr = [];

// 객체 리터럴(Object Literal)
const obj = {};

템플릿 리터럴은 말 그대로 리터럴을 템플릿 형태로 사용하는 자바스크립트의 문법입니다. basckticks(`)를 사용하여 문자열을 작성하고 그 안에 대체 가능한 experession을 넣는 방법입니다. expression을 substitution이라고도 부릅니다. 템플릿 리터럴은 또 크게 언태그드 템플릿 리터럴과 태그드 템플릿 리터럴로 나뉩니다. 아래 예제 코드를 봅시다.

// Untagged template literal
// 단순한 문자열
`string text`

// 여러 줄에 걸친 문자열
`string text line 1
string text line 2`

// 대체 가능한 expression이 들어있는 문자열
`string text ${expression} string text`

// Tagged template literal
// myFunction의 파라미터로 expression으로 구분된 문자열 배열과 expression이 
// 순서대로 들어간 형태로 호출됨
myFunction`string text ${expression} string text`;

언태그드 템플릿 리터럴은 보통 문자열을 여러 줄에 걸쳐서 작성하고나 포매팅을 하기 위해서 사용합니다. 태그드 탬플릿 리터럴은 앞에 나와있는 태그 함수를 호출하여 결과를 리턴합니다. 여기에서 태그 함수의 파라미터는 expression으로 구분된 문자열 배열과 expression이 순서대로 들어가게 됩니다. 좀 더 쉬운 이해를 위해 아래 코드를 봅시다.

const name = '인제';
const region = '서울';

function myTagFunction(strings, nameExp, regionExp) {
	let str0 = strings[0]; // "제 이름은 "
    let str1 = strings[1]; // "이고, 사는 곳은 "
    let str2 = strings[2]; // "입니다."
    
    // 여기에서도 template literal을 사용하여 리턴할 수 있음
    return `${str[0]}${nameExp}${str[1]}${regionExp}${str[2]}`;
}

const output = myTagFunction`제 이름은 ${name}이고, 사는 곳은 ${region}입니다.`;

// 출력 결과 : 제 이름은 인제이고, 사는 곳은 서울입니다.
console.log(output);

styled-components는 태그드 템플릿 리터럴을 사용하여 CSS 속성이 적용된 리액트 컴포넌트를 만들어줍니다. backticks(`)로 둘러싸인 문자열 부분에 CSS 속성을 넣고 태그 함수 위치에는 styled.<HTML 태그> 형태로 사용합니다. 이렇게 하면 해당 HTML 태그에 CSS 속성들이 적용된 형태의 리액트 컴포넌트가 만들어집니다.

import React from "react";
import styled from "styled-components";

const Wrapper = styled.div`
	padding: 1em;
    background: grey;
`;

3. styled-components의 props 사용하기

style-components에서는 조건이나 동적으로 변하는 값을 사용해서 스타일링할 수도 있습니다. 이것을 위해 제공하는 기능이 바로 props입니다. 다음 예제 코드를 봅시다.

import React from 'react';
import styled from 'styled-components';

const Button = styled.button`
	color: ${props => props.dark ? "white" : "black"};
    background: ${props => props.dark ? "black" : "white"};
    border: 1px solid black;
`;

function Sample(props) {
	return (
    	<div>
        	<Button>Normal</Button>
            <Button dark>Dark</Button>
        </div>
    );
}

export default Sample;

위 코드의 Button 컴포넌트는 styled-components를 사용해서 만들어진 것입니다. 그리고 styled-components를 사용하는 부분의 CSS 속성을 보면 내부에 props가 사용된 것을 볼 수 있습니다. 여기에서의 props는 해당 컴포넌트에 사용된 props를 의미합니다. 따라서 실제 Button 컴포넌트를 사용하는 부분의 코드의 <Button dark>처럼 props로 dark를 넣어주는 것을 볼 수 있습니다. 그리고 이렇게 들어간 props는 그대로 styled-components로 전달됩니다. 이 기능을 사용하면 styled-components를 사용하여 다양한 스타일을 자유자재로 구현할 수 있습니다.

4. styled-components의 스타일 확장하기

 

styled-components에서는 생성된 컴포넌트를 기반으로 추가적인 스타일을 적용할 수 있는 스타일 확장 기능을 제공합니다. 아래 예제를 봅시다.

import React from 'react';
import styled from 'styled-components';

// Button 컴포넌트
const Button = styled.button`
	color: grey;
    border: 2px solid palevioletred;
`;

// Button에 style이 추가된 RoundedButton 컴포넌트
const RoundButton = styled(Button)`
	border-radius: 16px;
`;

function Sample(props) {
	return (
    	<div>
        	<Button>Normal</Button>
            <RoundedButton>Rounded</RoundedButton>
        </div>
    );
}

Button 컴포넌트는 HTML의 button 태그를 기반으로 만들어진 단순한 버튼입니다. 그리고 RoundedButton은 Button 컴포넌트에서 모서리를 둥글게 만든 컴포넌트입니다. 

 

styled-components를 사용하면 더 다양한 형태로 스타일을 확장할 수 있지만 이 부분은 공식 문서 등을 통해 스스로 공부해보시길 추천합니다. 

'개발 공부' 카테고리의 다른 글

데이터 파이프라인에 대하여  (0) 2025.05.01
[Front-end] React 컨텍스트  (1) 2023.10.18
[Front-end] React 합성 vs. 상속  (0) 2023.10.16
[Front-end] React 폼  (0) 2023.10.01
[Front-end] React 리스트와 키  (0) 2023.10.01