Code Guide by @mdo / 한국어 번역 by @aliencubeorg

유연하고, 강인하고, 지속 가능한 HTML과 CSS 개발의 표준

목차

HTML

CSS

규칙

여기서 논의하는 가이드라인 또는 당신이 정한 가이드라인을 항상 따릅니다. 무엇인가 틀렸다면 그것이 작건 크건 상관 없이 논의합니다. 이 코딩 가이드라인에 내용을 추가한다거나 참여하고 싶다면 깃헙에 이슈를 생성하세요.

프로젝트 참여자들 중 누가 하든 상관 없이 코드는 마치 한 사람이 쓴 것 처럼 보여야 합니다.

HTML

문법

<!DOCTYPE html>
<html>
  <head>
    <title>Page title</title>
  </head>
  <body>
    <img src="images/company-logo.png" alt="Company">
    <h1 class="hello-world">Hello, world!</h1>
  </body>
</html>

HTML5 문서 타입

모든 HTML 페이지의 시작에 이 문서 타입을 선언함으로써, 표준 모드를 사용하게끔 강제합니다. 그렇게 하면 모든 브라우저에서 좀 더 일관적으로 렌더링을 할 수 있습니다.

<!DOCTYPE html>
<html>
  <head>
  </head>
</html>

언어 속성

HTML5 스펙의 정의는 아래와 같습니다:

작성자는 문서에 쓰인 언어를 알리기 위해 lang 속성을 루트의 html 엘리먼트에 명시하는 것이 좋다. 이것은 텍스트 리더기와 같은 도구들이 어떤 언어와 발음를 써야 하는지, 어떤 번역 도구를 써야 하는지 등에 대해 내부적으로 결정할 수 있게 도와준다.

lang 속성에 대해 더 자세하게 알고 싶으면 이 스펙을 참고하세요.

Sitepoint 웹사이트에서 언어 코드에 대한 리스트를 볼 수 있습니다.

<html lang="en-us">
  <!-- ... -->
</html>

인터넷 익스플로러 호환 모드

인터넷 익스플로러는 <meta> 태그를 통해 어떤 버전의 인터넷 익스플로러를 사용해야 하는지를 명시함으로써 문서의 호환성을 지원합니다. 딱히 특별한 상황이 아니라면 엣지 모드를 사용하여 인터넷 익스플로러에게 가장 최신 버전을 사용하라고 하면 됩니다.

이 스택 오버플로우 글에서 더 많은 내용들을 확인할 수 있습니다.

<meta http-equiv="X-UA-Compatible" content="IE=Edge">

문자열 인코딩

문자열 인코딩을 명시적으로 선언함으로써, 당신의 콘텐츠를 빠르고 쉽게 정확한 방법으로 렌더링할 수 있습니다. 이렇게 하면 당신의 문서에 명시한 인코딩 (일반적으로 utf-8)과 문서의 인코딩이 일치하는 경우 HTML 문서 안에서 문자 엔티티들을 쓰지 않아도 됩니다.

<head>
  <meta charset="UTF-8">
</head>

CSS/자바스크립트 인클루드

HTML5 스펙에 따르면 일반적으로는 CSS와 자바스크립트 파일을 불러올 때 type 속성을 선언할 필요가 없습니다. text/csstext/javascript 속성값이 각각의 기본값입니다.

읽어볼 만한 HTML5 스펙 링크들:

<!-- External CSS -->
<link rel="stylesheet" href="code-guide.css">

<!-- In-document CSS -->
<style>
  /* ... */
</style>

<!-- JavaScript -->
<script src="code-guide.js"></script>

실용성 vs 순수성

실용성을 잃지 않는 선에서 가능한 한 HTML 표준과 시만틱을 유지하세요. 가능한 한 복잡함을 줄이면서 최소한의 마크업을 사용하는 것이 좋습니다.

태그 속성 순서

HTML 태그 속성들은 코드의 가독성 향상을 위해 특정 순서로 놓는 것이 좋습니다.

class는 콤포넌트의 재사용성을 높여주기 때문에 가장 먼저 오게 합니다. id는 좀 더 구체적이고 제한적으로 쓰이므로 두 번째로 오게 합니다.

<a class="..." id="..." data-modal="toggle" href="#">
  Example link
</a>

<input class="form-control" type="text">

<img src="..." alt="...">

불리언 태그 속성

불리언 태그 속성은 굳이 속성값을 지정할 필요가 없습니다. XHTML에서는 속성값 지정이 필요했지만 HTML5에서는 그런 제약이 없어졌습니다.

불리언 태그 속성에 대한 WhatWG 섹션에는 이렇게 나와 있습니다:

불리언 태그 속성이 태그 안에 존재한다는 것 자체가 true를 의미한다. 반대로 불리언 태그 속성이 태그 안에 선언되지 않았다면 그것은 false를 의미한다.

만약 태그 숙성값을 반드시 포함시켜야 하지만 사실은 그럴 필요가 없다면, 다음의 WhatWG 가이드라인을 따르세요:

만약 속성값이 필요하다면 그 값은 반드시 공백문자를 포함하지 않은 빈 문자열이거나 또는 속성의 이름이어야 한다.

다시 정리하자면, 그냥 속성값을 넣지 마세요.

<input type="text" disabled>

<input type="checkbox" value="1" checked>

<select>
  <option value="1" selected>1</option>
</select>

마크업 최소화

가능하다면 항상 HTML 마크업 작성시 불필요한 부모 엘리먼트들을 피하세요. 많은 경우 리팩토링이 필요합니다. 다음의 예제를 확인해 보세요:

<!-- Not so great -->
<span class="avatar">
  <img src="...">
</span>

<!-- Better -->
<img class="avatar" src="...">

자바스크립트가 생성하는 마크업

자바스크립트 안에 마크업을 쓰는 것인 콘텐츠를 찾고 수정하기가 힘듭니다. 게다가 효율적이지도 않죠. 가급적이면 피하는 것이 좋습니다.

CSS

문법

여기 쓰인 용어들이 궁금하세요? 위키피디아의 CSS 문법 섹션을 확인하세요.

/* Bad CSS */
.selector, .selector-secondary, .selector[type=text] {
  padding:15px;
  margin:0px 0px 15px;
  background-color:rgba(0, 0, 0, 0.5);
  box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
}

/* Good CSS */
.selector,
.selector-secondary,
.selector[type="text"] {
  padding: 15px;
  margin-bottom: 15px;
  background-color: rgba(0,0,0,.5);
  box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}

속성 선언 순서

관련 속성에 대한 선언들은 아래와 같은 순서로 묶어야 합니다:

  1. 포지션 관련
  2. 박스 모델
  3. 타이포그라피
  4. 시각 효과

포지션 관련 선언들이 가장 먼저 옵니다. 문서의 정상적인 흐름에서 엘리먼트들을 없앨 수 있고, 박스 모델 관련 스타일들을 재정의할 수 있기 때문입니다. 박스 모델이 그 다음으로 오는데, 이것은 해당 엘리먼트의 크기와 위치를 지정하기 때문입니다.

나머지는 이 앞의 두 섹션에 영향을 주지 않거나 해당 엘리먼트의 내부에서만 일어나기 때문에 나중에 배치 시킵니다.

모든 속성들의 리스트와 그 순서를 확인하고 싶다면 이 Recess 링크를 확인하세요.

.declaration-order {
  /* Positioning */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;

  /* Box-model */
  display: block;
  float: right;
  width: 100px;
  height: 100px;

  /* Typography */
  font: normal 13px "Helvetica Neue", sans-serif;
  line-height: 1.5;
  color: #333;
  text-align: center;

  /* Visual */
  background-color: #f5f5f5;
  border: 1px solid #e5e5e5;
  border-radius: 3px;

  /* Misc */
  opacity: 1;
}

@import 사용 금지

<link>에 비해 @import는 상대적으로 느리고 추가 페이지 요청을 필요로 하기 때문에 결과적으로 예측할 수 없는 문제를 야기할 수 있습니다. @import의 사용을 피하는 대신 다른 방법을 써 보세요:

Steve Souders가 쓴 이 글을 읽어보시길 권합니다.

<!-- Use link elements -->
<link rel="stylesheet" href="core.css">

<!-- Avoid @imports -->
<style>
  @import url("more.css");
</style>

미디어 쿼리 위치

가급적이면 관련 규칙들이 모여 있는 곳에 미디어 쿼리들을 최대한 가까이 모아 놓으세요. 미디어 쿼리들을 별도의 스타일시트에 묶어 놓는다든가 문서의 맨 마지막에 놓는 것은 좋지 않습니다. 이렇게 하는 것이 오히려 나중에 까먹기 딱 좋습니다. 일반적인 설정은 다음과 같습니다.

.element { ... }
.element-avatar { ... }
.element-selected { ... }

@media (min-width: 480px) {
  .element { ...}
  .element-avatar { ... }
  .element-selected { ... }
}

접두사가 있는 속성

브라우저별 접두사가 있는 속성들을 사용할 경우 각각의 속성들을 들여쓰기 하세요. 그렇게 함으로써 해당 선언들의 값이 수직으로 정렬되어 여러 줄을 한꺼번에 수정하는 것이 가능해 집니다.

Textmate 에서는 Text → Edit Each Line in Selection (⌃⌘A) 기능이 있습니다. Sublime Text 2 에서는, Selection → Add Previous Line (⌃⇧↑) 선택 후 Selection → Add Next Line (⌃⇧↓) 메뉴를 선택하면 됩니다. (모두 맥용 환경을 기준으로 언급하고 있다 – 역자 주)

/* Prefixed properties */
.selector {
  -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
          box-shadow: 0 1px 2px rgba(0,0,0,.15);
}

단일 선언문들을 위한 규칙

어떤 규칙 세트가 오직 하나의 선언만을 포함하는 경우가 있는데, 이럴 땐 가독성과 빠른 편집을 위해 줄바꿈을 제거합니다. 여러 개의 선언문을 가진 규칙 세트가 있을 때에는 당연히 줄바꿈을 해야 합니다.

이렇게 하는 가장 큰 목적은 에러 확인입니다. 예를 들어 CSS 검수기가 183번째 줄에 에러가 있다고 할 때, 단일 선언문에서야 금방 찾을 수 있지만, 다중 선언문에서는 줄바꿈을 하는 것이 이렇게 에러 확인을 할 때 필수 요소가 될 수 있습니다.

/* Single declarations on one line */
.span1 { width: 60px; }
.span2 { width: 140px; }
.span3 { width: 220px; }

/* Multiple declarations, one per line */
.sprite {
  display: inline-block;
  width: 16px;
  height: 15px;
  background-image: url(../img/sprite.png);
}
.icon           { background-position: 0 0; }
.icon-home      { background-position: 0 -20px; }
.icon-account   { background-position: 0 -40px; }

축약형

모든 가능한 속성값들을 명시적으로 설정해야만 하는 경우에는 축약형 선언문을 사용하지 않는 것이 좋습니다. 주로 이러한 축약형을 남용하는 속성들에는 아래와 같은 것들이 있습니다:

축약형 속성이 나타내는 모든 값들을 모두 설정할 필요가 없을 때가 종종 있습니다. 예를 들어 HTML 문서의 헤더 영역에서는 오로지 top/bottom 마진 정도만 필요하기 때문에 이 두 속성값들만 재정의하면 되는 경우가 많습니다. 축약형 속성들을 남용하게 되면 불필요하게 재정의하는 경우가 많아 원하지 않는 부작용이 발생합니다.

MDN (Mozilla Developer Network)에서 발행한 축약형 속성이라는 글에서는 이러한 낯선 경우와 행동들에 대해 잘 정리해 놓았습니다.

/* Bad example */
.element {
  margin: 0 0 10px;
  background: red;
  background: url("image.jpg");
  border-radius: 3px 3px 0 0;
}

/* Good example */
.element {
  margin-bottom: 10px;
  background-color: red;
  background-image: url("image.jpg");
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
}

LESS와 SASS 안에서 중첩시키기

불필요한 중첩은 피하세요. 중첩이 가능하다는 이유가 항상 그래야만 하는 것을 의미하는 것은 아닙니다. 중첩은 부모 엘리먼트 스코프 안에서만 해야 할 때 또는 여러 개의 엘리먼트들을 한꺼번에 중첩시킬 때나 필요합니다.

// Without nesting
.table > thead > tr > th {  }
.table > thead > tr > td {  }

// With nesting
.table > thead > tr {
  > th {  }
  > td {  }
}

주석

코드는 당연하게도 사람이 쓰고 유지보수를 합니다. 당신의 코드에 충분한 설명이 되어 있는지, 충분한 주석이 달려 있는지, 다른 사람들에 의해 접근이 가능한지를 항상 살펴야 합니다. 좋은 주석은 그 자체만으로도 맥락과 목적을 충분히 보여줍니다. 단순히 엘리먼트라든가 클라스 이름들을 주석 처리하는 것으로만 사용하지 마세요.

주석의 양이 많을 경우 완전한 문장으로 주석을 쓰세요. 그리고, 일반적인 노트의 경우에는 간단한 구문 만으로도 충분합니다.

/* Bad example */
/* Modal header */
.modal-header {
  ...
}

/* Good example */
/* Wrapping element for .modal-title and .modal-close */
.modal-header {
  ...
}

클라스 작명

SASS 또는 LESS의 변수명을 지정할 때에도 이러한 방법들은 대단히 유용합니다.

/* Bad example */
.t { ... }
.red { ... }
.header { ... }

/* Good example */
.tweet { ... }
.important { ... }
.tweet-header { ... }

선택자

추가 정보들은 이곳에서 확인할 수 있습니다:

/* Bad example */
span { ... }
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
.avatar { ... }

/* Good example */
.avatar { ... }
.tweet-header .username { ... }
.tweet .avatar { ... }

구성

/*
 * Component section heading
 */

.element { ... }


/*
 * Component section heading
 *
 * Sometimes you need to include optional context for the entire component. Do that up here if it's important enough.
 */

.element { ... }

/* Contextual sub-component or modifer */
.element-heading { ... }

에디터 설정

당신의 에디터를 다음과 같은 세팅으로 설정하여 다른 사람들과 협업시 일관성을 해치지 않도록 하세요:

이 설정들을 당신 프로젝트의 .editorconfig 파일에 저장 시킵니다. Bootstrap 설정파일을 참고하세요. EditorConfig를 참고하시면 더 많은 정보를 볼 수 있습니다.