Reboot

Reboot (리부트)

요소별 CSS 변경 모음인 Reboot는 단일 파일로 Bootstrap을 시작시켜 그 위에 쌓을 우아하고 일관되며 단순한 기반을 제공합니다.

출처: 문서

본문

접근 방식 (Approach)

Reboot는 Normalize 위에 구축되어 많은 HTML 요소에 요소 선택자만 사용해 다소 의견이 담긴 스타일을 제공합니다. 추가 스타일링은 클래스로만 이루어집니다. 예를 들어 어떤 <table> 스타일을 더 단순한 기준선을 위해 리부트하고, 나중에 .table, .table-bordered 등을 제공합니다.

Reboot에서 무엇을 덮어쓸지 선택하는 기준과 이유는 다음과 같습니다:

  • 확장 가능한 컴포넌트 간격을 위해 일부 브라우저 기본값을 ems 대신 rems을 사용하도록 업데이트합니다.
  • margin-top을 피합니다. 세로 마진은 겹쳐져 예상치 못한 결과를 낼 수 있습니다. 더 중요한 것은, margin의 한 방향만이 더 단순한 정신 모델이라는 것입니다.
  • 기기 크기에 걸쳐 더 쉽게 스케일링하기 위해 블록 요소는 margins에 rems을 사용해야 합니다.
  • 가능하면 inherit을 사용해 font-관련 속성 선언을 최소한으로 유지합니다.

CSS 변수 (CSS variables)

v5.2.0에서 추가됨

v5.1.1부터 모든 CSS 번들(bootstrap.css, bootstrap-reboot.css, bootstrap-grid.css 포함)의 필수 @imports에 _root.scss를 포함하도록 표준화했습니다. 이것은 번들에서 그 중 얼마를 사용하든 모든 번들에 :root 레벨 CSS 변수를 추가합니다. 궁극적으로 Bootstrap 5는 항상 Sass를 다시 컴파일하지 않고도 더 많은 실시간 커스터마이즈를 제공하기 위해 시간이 지남에 따라 더 많은 CSS 변수를 계속 추가할 것입니다. 우리의 접근 방식은 소스 Sass 변수를 가져와 CSS 변수로 변환하는 것입니다. 그렇게 하면 CSS 변수를 사용하지 않더라도 Sass의 모든 힘을 여전히 갖게 됩니다. 아직 진행 중이며 완전히 구현하는 데 시간이 걸릴 것입니다.

예를 들어 일반적인 <body> 스타일을 위한 다음 :root CSS 변수들을 생각해 보세요:

@if $font-size-root != null {
  --#{$prefix}root-font-size: #{$font-size-root};
}
--#{$prefix}body-font-family: #{inspect($font-family-base)};
@include rfs($font-size-base, --#{$prefix}body-font-size);
--#{$prefix}body-font-weight: #{$font-weight-base};
--#{$prefix}body-line-height: #{$line-height-base};
@if $body-text-align != null {
  --#{$prefix}body-text-align: #{$body-text-align};
}

--#{$prefix}body-color: #{$body-color};
--#{$prefix}body-color-rgb: #{to-rgb($body-color)};
--#{$prefix}body-bg: #{$body-bg};
--#{$prefix}body-bg-rgb: #{to-rgb($body-bg)};

--#{$prefix}emphasis-color: #{$body-emphasis-color};
--#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color)};

--#{$prefix}secondary-color: #{$body-secondary-color};
--#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color)};
--#{$prefix}secondary-bg: #{$body-secondary-bg};
--#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg)};

--#{$prefix}tertiary-color: #{$body-tertiary-color};
--#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color)};
--#{$prefix}tertiary-bg: #{$body-tertiary-bg};
--#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg)};

실제로 그 변수들은 Reboot에서 다음과 같이 적용됩니다:

body {
  margin: 0; // 1
  font-family: var(--#{$prefix}body-font-family);
  @include font-size(var(--#{$prefix}body-font-size));
  font-weight: var(--#{$prefix}body-font-weight);
  line-height: var(--#{$prefix}body-line-height);
  color: var(--#{$prefix}body-color);
  text-align: var(--#{$prefix}body-text-align);
  background-color: var(--#{$prefix}body-bg); // 2
  -webkit-text-size-adjust: 100%; // 3
  -webkit-tap-highlight-color: rgba($black, 0); // 4
}

이렇게 하면 원하는 대로 실시간 커스터마이즈를 할 수 있습니다:

<body style="--bs-body-color: #333;">
  <!-- ... -->
</body>

페이지 기본값 (Page defaults)

<html>과 <body> 요소는 더 나은 페이지 전체 기본값을 제공하도록 업데이트됩니다. 구체적으로:

  • box-sizing은 *::before와 *::after를 포함한 모든 요소에 전역적으로 border-box로 설정됩니다. 이렇게 하면 선언된 요소 너비가 패딩이나 테두리 때문에 초과되지 않습니다.
  • <html>에는 기본 font-size가 선언되지 않지만 16px이 가정됩니다(브라우저 기본값). <body>에는 font-size: 1rem이 적용되어 미디어 쿼리를 통한 쉬운 반응형 타입 스케일링을 허용하면서 사용자 선호를 존중하고 더 접근성 높은 접근 방식을 보장합니다. 이 브라우저 기본값은 $font-size-root 변수를 수정해 덮어쓸 수 있습니다.
  • <body>는 또한 전역 font-family, font-weight, line-height, color를 설정합니다. 이것은 나중에 일부 폼 요소가 상속하여 글꼴 불일치를 방지합니다.
  • 안전을 위해 <body>에는 기본적으로 #fff인 선언된 background-color가 있습니다.

네이티브 글꼴 스택 (Native font stack)

Bootstrap은 모든 기기와 OS에서 최적의 텍스트 렌더링을 위해 "네이티브 글꼴 스택" 또는 "시스템 글꼴 스택"을 활용합니다. 이 시스템 글꼴들은 오늘날의 기기들을 염두에 두고 설계되었으며, 화면에서의 개선된 렌더링, 가변 글꼴 지원 등을 갖추고 있습니다. 이 Smashing Magazine 기사에서 네이티브 글꼴 스택에 대해 더 읽어보세요.

$font-family-sans-serif:
  // Cross-platform generic font family (default user interface font)
  system-ui,
  // Safari for macOS and iOS (San Francisco)
  -apple-system,
  // Windows
  "Segoe UI",
  // Android
  Roboto,
  // older macOS and iOS
  "Helvetica Neue",
  // Linux
  "Noto Sans",
  "Liberation Sans",
  // Basic web fallback
  Arial,
  // Sans serif fallback
  sans-serif,
  // Emoji fonts
  "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;

글꼴 스택에 이모지 글꼴이 포함되어 있기 때문에 많은 일반적인 기호/단어 문자 유니코드 문자가 다색 픽토그래프로 렌더링된다는 점에 주의하세요. 그 모양은 브라우저/플랫폼의 네이티브 이모지 글꼴에 사용된 스타일에 따라 달라지며, 어떤 CSS color 스타일에도 영향을 받지 않습니다.

이 font-family는 <body>에 적용되고 Bootstrap 전체에 전역적으로 자동 상속됩니다. 전역 font-family를 바꾸려면 $font-family-base를 업데이트하고 Bootstrap을 다시 컴파일하세요.

제목 (Headings)

모든 제목 요소 — <h1>—<h6>은 margin-top이 제거되고 margin-bottom: .5rem이 설정되며 line-height가 조여집니다. 제목은 기본적으로 color를 상속하지만, 선택적 CSS 변수 --bs-heading-color로 덮어쓸 수도 있습니다.

제목 예시
<h1></h1> h1. Bootstrap heading
<h2></h2> h2. Bootstrap heading
<h3></h3> h3. Bootstrap heading
<h4></h4> h4. Bootstrap heading
<h5></h5> h5. Bootstrap heading
<h6></h6> h6. Bootstrap heading

단락 (Paragraphs)

모든 <p> 요소는 쉬운 간격을 위해 margin-top이 제거되고 margin-bottom: 1rem이 설정됩니다.

<p>This is an example paragraph.</p>

링크에는 기본 color와 밑줄이 적용됩니다. 링크는 :hover에서 바뀌지만, 누군가 링크를 :visited했는지에 따라 바뀌지는 않습니다. 특별한 :focus 스타일도 받지 않습니다.

<a href="#">This is an example link</a>

v5.3.x부터 링크 color는 rgba()와 새로운 -rgb CSS 변수를 사용해 설정되며, 링크 색상의 불투명도를 쉽게 커스터마이즈할 수 있습니다. --bs-link-opacity CSS 변수로 링크 색상 불투명도를 바꾸세요:

<a href="#" style="--bs-link-opacity: .5">This is an example link</a>

플레이스홀더 링크 — href가 없는 것들 — 은 더 구체적인 선택자로 대상이 지정되고 color와 text-decoration이 기본값으로 재설정됩니다.

<a>This is a placeholder link</a>

수평선 (Horizontal rules)

<hr> 요소는 단순화되었습니다. 브라우저 기본값과 비슷하게 <hr>s는 border-top으로 스타일되며 기본 opacity: .25를 갖고, 부모를 통해 color가 설정된 경우를 포함해 color를 통해 border-color를 자동으로 상속합니다. 텍스트, 테두리, 불투명도 유틸리티로 수정할 수 있습니다.

<hr>

<div class="text-success">
  <hr>
</div>

<hr class="border border-danger border-2 opacity-50">
<hr class="border border-primary border-3 opacity-75">

목록 (Lists)

모든 목록 — <ul>, <ol>, <dl> — 은 margin-top이 제거되고 margin-bottom: 1rem이 설정됩니다. 중첩 목록은 margin-bottom이 없습니다. 또한 <ul>과 <ol> 요소의 padding-left도 재설정했습니다.

<ul>
  <li>All lists have their top margin removed</li>
  <li>And their bottom margin normalized</li>
  <li>Nested lists have no bottom margin</li>
  <li>This way they have a more even appearance</li>
  <li>Particularly when followed by more list items</li>
  <li>The left padding has also been reset</li>
</ul>

<ol>
  <li>Here’s an ordered list</li>
  <li>With a few list items</li>
  <li>It has the same overall look</li>
  <li>As the previous unordered list</li>
</ol>

더 단순한 스타일, 명확한 계층, 더 나은 간격을 위해 설명 목록은 업데이트된 margins를 갖습니다. <dd>s는 margin-left를 0으로 재설정하고 margin-bottom: .5rem을 추가합니다. <dt>s는 굵게 표시됩니다.

<dl>
  <dt>Description lists</dt>
  <dd>A description list is perfect for defining terms.</dd>
  <dt>Term</dt>
  <dd>Definition for the term.</dd>
  <dd>A second definition for the same term.</dd>
  <dt>Another term</dt>
  <dd>Definition for this other term.</dd>
</dl>

인라인 코드 (Inline code)

인라인 코드 스니펫을 <code>로 감싸세요. HTML 각도 괄호를 이스케이프해야 합니다.

For example, <code>&lt;section&gt;</code> should be wrapped as inline.

코드 블록 (Code blocks)

여러 줄의 코드에는 <pre>s를 사용하세요. 다시 한 번, 올바른 렌더링을 위해 코드의 모든 각도 괄호를 이스케이프하세요. <pre> 요소는 margin-top을 제거하고 margin-bottom에 rem 단위를 사용하도록 재설정됩니다.

<pre><code>&lt;p&gt;Sample text here...&lt;/p&gt;
&lt;p&gt;And another line of sample text here...&lt;/p&gt;
</code></pre>

변수 (Variables)

변수를 나타낼 때는 <var> 태그를 사용하세요.

<var>y</var> = <var>m</var><var>x</var> + <var>b</var>

사용자 입력 (User input)

일반적으로 키보드로 입력되는 입력을 나타낼 때는 <kbd>를 사용하세요.

To switch directories, type <kbd>cd</kbd> followed by the name of the directory.<br>
To edit settings, press <kbd><kbd>Ctrl</kbd> + <kbd>,</kbd></kbd>

샘플 출력 (Sample output)

프로그램의 샘플 출력을 나타낼 때는 <samp> 태그를 사용하세요.

<samp>This text is meant to be treated as sample output from a computer program.</samp>

테이블 (Tables)

테이블은 <caption>s를 스타일하고, 테두리를 접고, 전체에 걸쳐 일관된 text-align을 보장하도록 약간 조정됩니다. 테두리, 패딩 등에 대한 추가 변경은 .table 클래스와 함께 제공됩니다.

<table>
  <caption>
    This is an example table, and this is its caption to describe the contents.
  </caption>
  <thead>
    <tr>
      <th>Table heading</th>
      <th>Table heading</th>
      <th>Table heading</th>
      <th>Table heading</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
    </tr>
    <tr>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
    </tr>
    <tr>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
      <td>Table cell</td>
    </tr>
  </tbody>
</table>

폼 (Forms)

더 단순한 기본 스타일을 위해 다양한 폼 요소가 리부트되었습니다. 가장 주목할 만한 변경 사항 중 일부는 다음과 같습니다:

  • <fieldset>s는 테두리, 패딩, 마진이 없어 개별 입력 또는 입력 그룹의 래퍼로 쉽게 사용할 수 있습니다.
  • <legend>s도 fieldset처럼 일종의 제목으로 표시되도록 재스타일되었습니다.
  • <label>s는 margin을 적용할 수 있도록 display: inline-block으로 설정됩니다.
  • <input>s, <select>s, <textarea>s, <button>s는 대부분 Normalize가 다루지만, Reboot는 그 margin을 제거하고 line-height: inherit도 설정합니다.
  • <textarea>s는 가로 리사이징이 페이지 레이아웃을 자주 "깨뜨리므로" 세로로만 리사이즈 가능하도록 수정됩니다.
  • <button>s와 <input> 버튼 요소는 :not(:disabled)일 때 cursor: pointer를 가집니다.

이 변경 사항들과 더 많은 것들이 아래에 시연됩니다.

일부 date 입력 타입은 최신 버전의 Safari와 Firefox에서 완전히 지원되지 않습니다.

<fieldset>
  <legend>Example legend</legend>
  <p>
    <label for="input">Example input</label>
    <input type="text" id="input" placeholder="Example input">
  </p>
  <p>
    <label for="email">Example email</label>
    <input type="email" id="email" placeholder="[email protected]">
  </p>
  <p>
    <label for="tel">Example telephone</label>
    <input type="tel" id="tel">
  </p>
  <p>
    <label for="url">Example url</label>
    <input type="url" id="url">
  </p>
  <p>
    <label for="number">Example number</label>
    <input type="number" id="number">
  </p>
  <p>
    <label for="search">Example search</label>
    <input type="search" id="search">
  </p>
  <p>
    <label for="range">Example range</label>
    <input type="range" id="range" min="0" max="10">
  </p>
  <p>
    <label for="file">Example file input</label>
    <input type="file" id="file">
  </p>
  <p>
    <label for="select">Example select</label>
    <select id="select">
      <option value="">Choose...</option>
      <optgroup label="Option group 1">
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
        <option value="3">Option 3</option>
      </optgroup>
      <optgroup label="Option group 2">
        <option value="4">Option 4</option>
        <option value="5">Option 5</option>
        <option value="6">Option 6</option>
      </optgroup>
    </select>
  </p>
  <p>
    <label>
      <input type="checkbox" value="">
      Check this checkbox
    </label>
  </p>
  <p>
    <label>
      <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
      Option one is this and that
    </label>
    <label>
      <input type="radio" name="optionsRadios" id="optionsRadios2" value="option2">
      Option two is something else that’s also super long to demonstrate the wrapping of these fancy form controls.
    </label>
    <label>
      <input type="radio" name="optionsRadios" id="optionsRadios3" value="option3" disabled>
      Option three is disabled
    </label>
  </p>
  <p>
    <label for="textarea">Example textarea</label>
    <textarea id="textarea" rows="3"></textarea>
  </p>
  <p>
    <label for="date">Example date</label>
    <input type="date" id="date">
  </p>
  <p>
    <label for="time">Example time</label>
    <input type="time" id="time">
  </p>
  <p>
    <label for="password">Example password</label>
    <input type="password" id="password">
  </p>
  <p>
    <label for="datetime-local">Example datetime-local</label>
    <input type="datetime-local" id="datetime-local">
  </p>
  <p>
    <label for="week">Example week</label>
    <input type="week" id="week">
  </p>
  <p>
    <label for="month">Example month</label>
    <input type="month" id="month">
  </p>
  <p>
    <label for="color">Example color</label>
    <input type="color" id="color" value="#563d7c">
  </p>
  <p>
    <label for="output">Example output</label>
    <output name="result" id="output">100</output>
  </p>
  <p>
    <button type="button" class="btn btn-primary">Button submit</button>
    <button type="button" class="btn btn-default">Button submit</button>
  </p>
</fieldset>

버튼의 포인터 (Pointers on buttons)

Reboot에는 기본 커서를 pointer로 바꾸기 위한 role="button"의 향상이 포함되어 있습니다. 요소가 상호작용적임을 나타내기 위해 이 속성을 요소에 추가하세요. 이 role은 자체 cursor 변경을 받는 <button> 요소에는 필요하지 않습니다.

<span role="button" tabindex="0">Non-button element button</span>

기타 요소 (Misc elements)

Address

<address> 요소는 브라우저 기본 font-style을 italic에서 normal로 재설정하도록 업데이트됩니다. line-height도 이제 상속되며 margin-bottom: 1rem이 추가되었습니다. <address>s는 가장 가까운 조상(또는 전체 저작물)의 연락처 정보를 제시하기 위한 것입니다. 줄을 <br>로 끝내서 서식을 유지하세요.

<address>
  <strong>ACME Corporation</strong><br>
  1123 Fictional St,<br>
  San Francisco, CA 94103<br>
  <abbr title="Phone">P:</abbr> (123) 456-7890
</address>

<address>
  <strong>Full Name</strong><br>
  <a href="mailto:[email protected]">[email protected]</a>
</address>

Blockquote

blockquote의 기본 margin은 1em 40px이므로, 다른 요소들과 더 일관되도록 0 0 1rem으로 재설정합니다.

<blockquote class="blockquote">
  <p>A well-known quote, contained in a blockquote element.</p>
  <footer class="blockquote-footer">Someone famous in <cite title="Source Title">Source Title</cite></footer>
</blockquote>

인라인 요소 (Inline elements)

<abbr> 요소는 단락 텍스트 사이에서 눈에 띄게 하기 위한 기본 스타일을 받습니다.

<p>An abbreviation of the word attribute is <abbr title="attribute">attr</abbr>.</p>

Summary

summary의 기본 cursor는 text이므로, 클릭으로 상호작용할 수 있음을 전달하기 위해 pointer로 재설정합니다.

<details>
  <summary>Some details</summary>
  <p>More info about the details.</p>
</details>

<details open>
  <summary>Even more details</summary>
  <p>Here are even more details about the details.</p>
</details>

HTML5 [hidden] 속성

HTML5는 기본적으로 display: none으로 스타일되는 [hidden]이라는 새 전역 속성을 추가합니다. PureCSS의 아이디어를 차용해 [hidden] { display: none !important; }로 만들어 display가 실수로 덮어써지는 것을 막는 방식으로 이 기본값을 개선합니다.

<input type="text" hidden>

[hidden]은 jQuery의 $(...).hide()와 $(...).show() 메서드와 호환되지 않으므로, 요소의 display를 관리하는 다른 기법보다 [hidden]을 특별히 권장하지는 않습니다.

요소의 가시성만 토글하고 싶다면 — 즉 display를 수정하지 않고 요소가 문서 흐름에 계속 영향을 줄 수 있다면 — .invisible 클래스를 대신 사용하세요.

더 알아보기 (Learn more)