CSS를 작성할 때 피해야 하는 9가지 실수

1. 대체 글꼴(Fallback) 미사용

기본 중의 기본인데 잘 지켜지지 않습니다.

다양한 글꼴을 웹에 사용하면 보기 좋은 웹 페이지를 만들 수 있지만, 지정한 글꼴을 가져올 수 없을 경우에 대한 대비를 항상 해야 합니다.

외부 사이트의 CDN 글꼴을 가져다 사용할 때, 일시적으로 글꼴을 가져올 수 없다면 웹 브라우저 설정에 정해진 기본 글꼴이 표시되고, 경우에 따라서는 웹페이지 레이아웃이 밀리면서 레이아웃 깨져 보일 수도 있습니다.

글꼴은 크게 삐침이 있는 글꼴과 삐침이 없는 글꼴로 구분합니다.

삐침이 있는 글꼴은 "serif", 삐침이 없는 글꼴은 "san-serif"로 계열을 구분하고, 한글로는 "세리프", "산세리프"로 사용합니다.

세리프 계열의 글꼴은 Courier, Courier New, 명조체, 바탕체 같은 글꼴들이 해당됩니다.

산세리프 계열의 글꼴은 Arial, Arial Black, Tahoma, 돋움체, 고딕체와 같은 글꼴들이 해당됩니다.

사용하려는 글꼴이 CDN으로 연결되어 있지도 않고, 시스템 글꼴로도 없다면 최대한 같은 계열의 글꼴이 표시될 수 있도록 폴백(Fallback) - 호환성 - 글꼴을 명시해야 합니다.

사용할 글꼴 선언을 할 때는 다음과 같이 사용하려는 글꼴의 계열에 맞춰 "serif" 또는 "san-serif"를 끝에 명시해줌으로써 사용하려는 글꼴이 없을 때 최대한 같은 계열의 글꼴을 가져오도록 해야 합니다.

다음과 같이 선언하면 앞에서부터 순서대로 글꼴이 있는지 확인한 후, 모두 없으면 마지막 선언된 "san-serif" 그러니까 삐침 없는 돋움체 계열의 사용 가능한 시스템 글꼴 중 산세리프 글꼴, 또는 웹 브라우저의 기본 설정 산세리프 글꼴을 가져오게 됩니다.

.content {
	font-family: 'Nanum Gothic', 'Malgun Gothic'. san-serif;
}

2. px 단위 사용

세상이 변했습니다. 웹의 세상도 변했고, 사용하는 방식도 변했습니다.

그중 가장 급격하게 변한 웹 환경이 사용 단위의 변경입니다.

절대 크기로 정확하게 짜여진 픽셀 단위로 구현된 웹 레이아웃은 더 이상 웹에서는 좋은 사용방법이 아닙니다. 

세상의 모든 것이 모바일 중심으로 변하고 있고, 다양한 모바일 디바이스에 보기 좋게 출력되는 웹 페이지를 제작하는 것이 필수 항목이 되었습니다.

다양한 해상도와, 다양한 픽셀 밀도를 가진 기기들을 절대 단위 값만으로 지원하는 것은 거의 불가능합니다.

그래서 상대 측정 단위인 em, rem, %, vw/vh 와 같은 단위를 사용해야 합니다.

다음과 같은 픽셀 단위 보다는

.content {
	font-size: 16px;
	line-height: 20px;
	padding: 8px;
}

다음과 같은 상대 단위 표현을 사용해야 합니다.

.content {
	font-size: 1em;
	line-height: 1.25em;
	padding: 0.5em;
}

3. 컬러 이름으로 컬러 값 사용하기

웹에서 컬러를 표현하는 방법은 여러 가지가 있습니다.

그중에서 가장 알아보기 쉽고 사용자 친화적인 방식이 영문 컬러명을 사용하는 것입니다. "color: red;"로 표현하는 컬러 속성 표현은 누가 봐도 빨간색입니다.

문제는 이 빨간색의 정의가 사람에 따라, 또는 문화권에 따라 다소 다른 색상이 될 수 있다는 것입니다. 정확하게 웹 16진수로 표현한 빨간색은 "#FF0000" 색상이지만, "#FA0000"도 약간 어두울 뿐 빨간색입니다. 그리고 모니터에서 보이게는 거의 같은 색으로 보입니다. 어느 게 빨간색이고 어느게 어두운 빨간색인지 구분하는 게 지극히 주관적이 문제가 됩니다.

비교적 쉬운 예를 들었지만, "AntiqueWhite", "AliceBlue"와 같은 색상이 어떤 색상인지를 이해할 수 있는 사람은 사실 거의 없습니다. 그리고 "AliceBlue"가 실제로는 파란색보다는 회색에 조금 더 가깝게 보인다는 것도 주관적인 해석으로 인한 색상 혼동 문제를 일으킵니다. "AliceBlue"는 16진수 색상으로 표현하면 "#F0F8FF" 이 되며, "Green"이 약간 더 있고, 그보다는 "Blue" 색상이 더 있는 약간 푸른기가 미세가 더 있는 색상이라는 것을 쉽게 알 수 있습니다.

물론 16진수 웹 컬러가 일반인이 보기에 어려운 기술적인 표현으로 보일 수는 있지만, CSS를 작성할 때는 주관적인 해석의 여지없이 정확히 어떤 색상이라는 구분을 할 수 있는 16진수 웹 컬러를 사용해야 합니다.

4. CSS 단축 표현 미사용

CSS는 상당히 많은 단축 표현을 지원합니다.

많이 사용하는 속성들은 대부분 단축 표현을 지원한다고 생각하면 됩니다.

여러 가지 단축 표현이 있지만, CSS를 작성할 때 쓰고 있으면서도 단축 표현인지를 모르고 쓰는 경우가 꽤 있습니다. 반대로 사용 방법이 다소 복잡하다 보니 사용하기 익숙하지 않아서 사용하지 않는 경우도 있습니다.

다음과 같이 개별 속성으로 표시한 글꼴 관련 속성들은 

font-family: 'nanum gothic';
font-size: 1em;
font-weight: bold;
font-height: 1.6;

다음과 같이 단축 속성으로 표시할 수 있습니다.

font: bold 1em/1.6 'nanum gothic';

그 밖에도 배경, 마진, 패딩, 테두리선 속성들 대표적으로 단축 표현을 많이 사용하는 속성입니다.

background: url(bg.jpg) repeat-y center center;
padding: 0 10px 5px 20px;
margin: 20px 10px;
border: 1px dashed #ff0000;

5. ID와 !important 남발

CSS를 작성할 때 가장 최악인 작성 방법이 ID와 !important를 남발하는 것입니다.

CSS의 기본 특징인 상속성과 일관성을 깨는 원인이 되는 속성이고, CSS 재사용성을 떨어뜨리는 요인이기도 합니다.

"!important"는 어떤 경우에든 가능하면 사용하지 않는 것이 좋습니다.

아주 특별히 예외적인 경우에만 사용해야 하고, "!important"를 우회해서 구현할 수 있는 CSS 구현이 있으면 우회하는 방법을 사용하는 것이 좋습니다.

ID는 적절히 사용하면 CSS 선택자를 줄여주는 중요한 역할을 합니다.

웹 페이지의 주요 영역을 구분하거나, 중요 요소를 직접 접근할 수 있는 단축 경로를 제공하기 때문에 

문제는 불필요한 ID를 남발해서 CSS의 재사용성을 떨어뜨리는 것입니다.

목록 아이템마다 ID를 적용해서 ID로 접근하는 다음과 같은 방식은 멍청한 방식입니다.

ul li#listitem7

다음처럼 CSS 실렉터만으로도 목록 요소에 직접 접근할 수 있으며, 다른 목록에서 적용할 수 있기 때문에 재사용성도 높아집니다.

ul li:nth-child(7)

6. CSS 리셋 미사용

CSS 초기화, 또는 CSS 리셋은 반복되는 CSS 코딩을 줄여주는 중요한 기초 작업입니다.

CSS 최상단에 작성한 CSS 리셋 코드는 이후에 작성하는 모든 CSS 코드의 기본값을 설정해주는 역할을 합니다. 상위 요소의 설정값이 하위 요소로 상속되는 특징을 가진 CSS는 처음 초기화를 잘해놓으면 이후의 CSS 코드 작성에서 잔손이 가는 많은 작업을 줄일 수 있습니다.

CSS 초기화를 하는 범위나 방법은 여러 가지가 있습니다.

경우에 따라서는 모든 태그의 많은 속성을 초기화하기도 하고, 경우에 따라서는 마진과 패딩 정도만 초기화를 하기도 합니다.

초기화를 하는 대표적인 이유 중 하나는 웹 브라우저간 호환성 때문입니다.

웹 브라우저에 따라 특정 태그에 기본 설정 값으로 사용하는 마진이나 패딩 값이 다른 경우가 있습니다. 특히 폼 요소들은 기본 글자 크기나 요소 사이의 간격 등 여러 가지 차이가 있기도 합니다.

모든 태그의 마진과 패딩만 초기화를 하려면 다음 CSS 초기화를 최 상단에 배치하면 됩니다.

* {margin: 0; padding: 0;}

모든 HTML 태그의 기본 속성을 초기화하려면 다음 CSS 초기화를 최 상단에 배치하면 됩니다.

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font-weight: inherit;
	font-style: inherit;
	font-size: 1em;
	font-family: inherit;
	vertical-align: baseline;
}

레이아웃을 작성할 때 플랫폼 간 호환성을 유지할 수 있도록 초기화를 하려면 다음 CSS 초기화를 최 상단에 배치하면 됩니다.

html {
	letter-spacing: 0px;
	font-family: -apple-system,BlinkMacSystemFont,"Malgun Gothic","맑은 고딕",helvetica,"Apple SD Gothic Neo",sans-serif;
}
html, body {
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
}
body {
	font-weight: normal;
	font-size: 1em;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;	
	line-height: 1.25;
	-webkit-text-size-adjust: 100%;
	background-size: cover;
	background-repeat: no-repeat;
	background-position: center;
	-webkit-background-size: cover;
	-moz-background-size: cover;
	-o-background-size: cover;
	background-size: cover;
	background-attachment: fixed;
}

7. 불필요하게 긴 CSS 선택자

CSS 선택자로 CSS 속성을 적용할 대상 요소를 선택하는 방법은 여러 가지가 있습니다.

그중 ID와 클래스를 대상으로 선택할 대상 범위를 한정하는 방법이 기본 방법입니다.

그러나 다음과 같이 작성한 CSS 선택자는 쓸데없이 너무 길게 작성한 것입니다.

main > .container > ul#topmenu > li > a > figure

ID는 웹 페이지 안에서 유일하며, 웹 사이트 전체에 걸쳐서 고유한 이름을 가진 ID는 CSS 작성 시 범용으로 사용할 수 있는 중요 ID입니다. 따라서 중요 ID가 적용된 대상을 선택할 때는 다음과 같이 줄여서 CSS를 작성하는 것이 맞습니다.

#topmenu > a > figure

앞에 붙은 

main > .container > ul

그리고 중간의 "li" 요소 선택자는 사실 완전히 필요가 없는 선택자입니다.

"li" 요소는 "ul" 태그 바로 밑에 목록 아이템으로 필수로 오는 태그이기 때문에 "li" 요소 하위 태그를 선택할 때는 선택자로 명시를 할 필요가 없습니다.

불필요하게 너무 넓은 범위에서부터 선택 대상을 한정하기 시작하기 때문에 CSS를 파싱 하는 시간만 낭비할 뿐 CSS 선택자로서 아무런 의미가 없습니다.

8. 레이아웃과 내용 표현의 혼용

잘 안 지켜지는 CSS 코드 작성 방법 중 하나입니다.

웹 사이트에 대한 설계가 완전하게 잘 된 상태에서 CSS를 작성하면 레이아웃 부분과 내용 표현 부분을 구분해서 작성하는 것이 어렵지 않지만, 부분 부분 빌드를 해나가는 경우 잘 지켜지기가 어렵습니다.

사실 레이아웃과 내용 표현을 구분해서 작성해야 한다는 것이 어떤 의미인지도 모르는 경우가 많습니다.

예를 들어 우리가 많이 봐왔던 익숙한 CSS는 다음과 같습니다.

.header {
    border-bottom: 1px solid #ccc;
    margin-bottom: 30px;
    font-size: 1em;
    line-height: 1.6;
}
.content {
    position: relative;
    display: inline-block;
    margin: 30px 0;
    padding: 30px;
    font-family: 'nanum gothic', sans-serif;
    font-size: 1em;
    line-height: 1.6;
    border-radius: 1em;
}
.sidebar {
    width: 25%;
    padding: 20px 15px;
    float: right;
    margin: 0 0 0 25px;
    font-size: 1em;
    line-height: 1.6;
}

레이아웃 부분과 내용 표현 부분을 구분해서 CSS를 작성하면 다음과 같이 나누어집니다.

/* layout */
.header {
    border-bottom: 1px solid #ccc;
    margin-bottom: 30px;
}
.content {
    position: relative;
    display: inline-block;
    margin: 30px 0;
    padding: 30px;
    border-radius: 1em;
}
.sidebar {
    width: 25%;
    padding: 20px 15px;
    float: right;
    margin: 0 0 0 25px;
}

/* content */
.header, .content, .sidebar {
    font-family: 'nanum gothic', sans-serif;
    font-size: 1em;
    line-height: 1.6;
}

레이아웃 부분과 내용 표현 부분을 나누어 작성하면 CSS 유지보수가 더 쉬워지고, 수정할 부분을 찾기가 용이해집니다.

또 레이아웃 부분을 수정해도 내용 부분이 영향을 받은 여지가 줄어들기 때문에 더 탄탄한 코드를 유지할 수 있습니다.

이런 방식은 팀 협업을 할 때 레이아웃을 담당하는 코더와 콘텐츠 영역의 데코레이션을 담당하는 코더가 작업을 나누기가 훨씬 편하기도 합니다.

9. 코멘트 없는 CSS 작성

CSS는 다른 언어에 비해 코멘트의 중요도가 다소 낮은 편입니다.

CSS 코드의 양이 그렇게 방대한 경우도 많지 않고, 용도에 따라 여러 개의 파일로 나누어 적용할 수 있기 때문에 코멘트를 신경 쓰지 않아도 원하는 CSS 코드 위치를 찾는 게 그렇게 어렵지 않습니다.

반응형 웹이 일반화되면서 하나의 CSS 파일 안에 미디어쿼리를 사용한 유사한 코드가 여러 군데 나오게 되었고, CSS 코드를 혼동할 가능성이 높아졌습니다.

거기에 더해 프레임워크와 프리프로세서를 사용하면서 자동으로 생성되는 CSS 코드가 많아지면서 자동 생성된 코드가 어떤 원 코드에서 파생된 코드인지를 구분을 할 수 있어야 합니다.

CSS 코드를 작성하는 코더의 CSS 네이밍 스타일이 다른 사용자가 보기에 다소 난해한 경우도 있기 때문에 CSS를 다른 사용자에게 제공할 때는 코멘트를 필수로 달아야 합니다.

그리고 CSS 파일의 코드가 긴 경우, 상단에 다음과 같이 섹션별 목차를 작성해서 코드 위치가 어디쯤인지 쉽게 알 수 있게 정리를 해놓는 것을 추천합니다.

/*
CSS CONTENTS:

01. Global Init
02. Reset
03. Accessibility Navigation
04. Layout Selector
05. Profile
06. SNS
07. Header
      Search
      Blogmenu
      Blog Title
      Menu
      Category Menu
      Mobile Category Menu
      Sub Category
08. Layout Container
09. Sidebar
      Box
      Search
      Tags
      List
      More Button
      Calendar
      Archive
      Visitor
      Recent Posts
      Google Translate
10. Content
11. Footer
12. Icons
*/