유틸리티 API
유틸리티 API (Utility API)
유틸리티 클래스를 생성하는 Sass 기반 도구예요.
출처: 문서
본문
Bootstrap 유틸리티는 유틸리티 API로 생성되며, Sass를 통해 기본 유틸리티 클래스 세트를 수정하거나 확장하는 데 사용할 수 있어요. 유틸리티 API는 다양한 옵션으로 클래스 패밀리를 생성하는 일련의 Sass 맵과 함수를 기반으로 해요. Sass 맵이 익숙하지 않다면 공식 Sass 문서를 읽고 시작해 보세요.
$utilities 맵은 모든 유틸리티를 담고 있으며, 사용자 정의 $utilities 맵이 있다면 나중에 그 맵과 병합돼요. 유틸리티 맵은 다음 옵션을 받는 유틸리티 그룹의 키 목록을 담고 있어요:
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
property |
필수 | – | 속성 이름. 문자열 또는 문자열 배열(예: 가로 패딩이나 마진)일 수 있어요. |
values |
필수 | – | 값 목록, 또는 클래스 이름이 값과 같지 않게 하고 싶다면 맵. 맵 키로 null을 사용하면 클래스 이름 앞에 클래스가 붙지 않아요. |
class |
선택 | null | 생성할 클래스의 이름. 제공되지 않고 property가 문자열 배열이면, 클래스는 property 배열의 첫 번째 요소로 기본 설정돼요. 제공되지 않고 property가 문자열이면, values 키가 클래스 이름으로 사용돼요. |
css-var |
선택 | false | CSS 규칙 대신 CSS 변수를 생성할지 여부. |
css-variable-name |
선택 | null | 규칙 세트 안 CSS 변수의 커스텀 접두어 없는 이름. |
local-vars |
선택 | null | CSS 규칙에 추가로 생성할 로컬 CSS 변수 맵. |
state |
선택 | null | 생성할 의사 클래스 변형 목록(예: :hover 또는 :focus). |
responsive |
선택 | false | 반응형 클래스를 생성할지 여부. |
rfs |
선택 | false | RFS로 유동 재스케일링을 활성화할지 여부. |
print |
선택 | false | print 클래스를 생성해야 하는지 여부. |
rtl |
선택 | true | 유틸리티를 RTL에 유지할지 여부. |
API 설명 (API explained)
모든 유틸리티 변수는 _utilities.scss 스타일시트의 $utilities 변수에 추가돼요. 각 유틸리티 그룹은 대략 이렇게 생겼어요:
$utilities: (
"opacity": (
property: opacity,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
이것은 다음을 출력해요:
.opacity-0 { opacity: 0; }
.opacity-25 { opacity: .25; }
.opacity-50 { opacity: .5; }
.opacity-75 { opacity: .75; }
.opacity-100 { opacity: 1; }
Property
필수 property 키는 어떤 유틸리티에든 설정해야 하며, 유효한 CSS 속성을 담아야 해요. 이 속성은 생성된 유틸리티의 규칙 세트에 사용돼요. class 키가 생략되면, 이 속성이 기본 클래스 이름 역할도 해요. text-decoration 유틸리티를 생각해 보세요:
$utilities: (
"text-decoration": (
property: text-decoration,
values: none underline line-through
)
);
출력:
.text-decoration-none { text-decoration: none !important; }
.text-decoration-underline { text-decoration: underline !important; }
.text-decoration-line-through { text-decoration: line-through !important; }
Values
values 키를 사용해 지정된 속성에 대해 생성된 클래스 이름과 규칙에 사용할 값을 지정해요. 목록 또는 맵(유틸리티 안에서 또는 Sass 변수로 설정)일 수 있어요.
목록으로는, text-decoration 유틸리티처럼:
values: none underline line-through
맵으로는, opacity 유틸리티처럼:
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
목록이나 맵을 설정하는 Sass 변수로는, position 유틸리티처럼:
values: $position-values
Class
class 옵션을 사용해 컴파일된 CSS에서 사용되는 클래스 접두어를 바꿀 수 있어요. 예를 들어 .opacity-*에서 .o-*로 바꾸려면:
$utilities: (
"opacity": (
property: opacity,
class: o,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
출력:
.o-0 { opacity: 0 !important; }
.o-25 { opacity: .25 !important; }
.o-50 { opacity: .5 !important; }
.o-75 { opacity: .75 !important; }
.o-100 { opacity: 1 !important; }
class: null이면, 각 values 키에 대해 클래스를 생성해요:
$utilities: (
"visibility": (
property: visibility,
class: null,
values: (
visible: visible,
invisible: hidden,
)
)
);
출력:
.visible { visibility: visible !important; }
.invisible { visibility: hidden !important; }
CSS 변수 유틸리티 (CSS variable utilities)
css-var 불리언 옵션을 true로 설정하면 API가 보통의 property: value 규칙 대신 주어진 선택자에 대한 로컬 CSS 변수를 생성해요. 클래스 이름과 다른 CSS 변수 이름을 설정하려면 선택 옵션 css-variable-name을 추가하세요.
.text-opacity-* 유틸리티를 생각해 보세요. css-variable-name 옵션을 추가하면 커스텀 출력을 얻게 돼요.
$utilities: (
"text-opacity": (
css-var: true,
css-variable-name: text-alpha,
class: text-opacity,
values: (
25: .25,
50: .5,
75: .75,
100: 1
)
),
);
출력:
.text-opacity-25 { --bs-text-alpha: .25; }
.text-opacity-50 { --bs-text-alpha: .5; }
.text-opacity-75 { --bs-text-alpha: .75; }
.text-opacity-100 { --bs-text-alpha: 1; }
로컬 CSS 변수 (Local CSS variables)
local-vars 옵션을 사용해 유틸리티 클래스 규칙 세트 안에서 로컬 CSS 변수를 생성할 Sass 맵을 지정할 수 있어요. 생성된 CSS 규칙에서 그 로컬 CSS 변수들을 소비하는 데 추가 작업이 필요할 수 있다는 점을 알아 두세요. 예를 들어 .bg-* 유틸리티를 생각해 보세요:
$utilities: (
"background-color": (
property: background-color,
class: bg,
local-vars: (
"bg-opacity": 1
),
values: map-merge(
$utilities-bg-colors,
(
"transparent": transparent
)
)
)
);
출력:
.bg-primary {
--bs-bg-opacity: 1;
background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;
}
상태 (States)
state 옵션을 사용해 의사 클래스 변형을 생성할 수 있어요. 예시 의사 클래스는 :hover와 :focus예요. 상태 목록이 제공되면 그 의사 클래스에 대한 클래스 이름이 생성돼요. 예를 들어 hover 시 opacity를 바꾸려면 state: hover를 추가하면 컴파일된 CSS에서 .opacity-hover:hover를 얻게 돼요.
여러 의사 클래스가 필요하세요? 상태를 공백으로 구분된 목록으로 사용하세요: state: hover focus.
$utilities: (
"opacity": (
property: opacity,
class: opacity,
state: hover,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
출력:
.opacity-0-hover:hover { opacity: 0 !important; }
.opacity-25-hover:hover { opacity: .25 !important; }
.opacity-50-hover:hover { opacity: .5 !important; }
.opacity-75-hover:hover { opacity: .75 !important; }
.opacity-100-hover:hover { opacity: 1 !important; }
반응형 (Responsive)
responsive 불리언을 추가해 모든 브레이크포인트에서 반응형 유틸리티(예: .opacity-md-25)를 생성할 수 있어요.
$utilities: (
"opacity": (
property: opacity,
responsive: true,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
출력:
.opacity-0 { opacity: 0 !important; }
.opacity-25 { opacity: .25 !important; }
.opacity-50 { opacity: .5 !important; }
.opacity-75 { opacity: .75 !important; }
.opacity-100 { opacity: 1 !important; }
@media (min-width: 576px) {
.opacity-sm-0 { opacity: 0 !important; }
.opacity-sm-25 { opacity: .25 !important; }
.opacity-sm-50 { opacity: .5 !important; }
.opacity-sm-75 { opacity: .75 !important; }
.opacity-sm-100 { opacity: 1 !important; }
}
@media (min-width: 768px) {
.opacity-md-0 { opacity: 0 !important; }
.opacity-md-25 { opacity: .25 !important; }
.opacity-md-50 { opacity: .5 !important; }
.opacity-md-75 { opacity: .75 !important; }
.opacity-md-100 { opacity: 1 !important; }
}
@media (min-width: 992px) {
.opacity-lg-0 { opacity: 0 !important; }
.opacity-lg-25 { opacity: .25 !important; }
.opacity-lg-50 { opacity: .5 !important; }
.opacity-lg-75 { opacity: .75 !important; }
.opacity-lg-100 { opacity: 1 !important; }
}
@media (min-width: 1200px) {
.opacity-xl-0 { opacity: 0 !important; }
.opacity-xl-25 { opacity: .25 !important; }
.opacity-xl-50 { opacity: .5 !important; }
.opacity-xl-75 { opacity: .75 !important; }
.opacity-xl-100 { opacity: 1 !important; }
}
@media (min-width: 1400px) {
.opacity-xxl-0 { opacity: 0 !important; }
.opacity-xxl-25 { opacity: .25 !important; }
.opacity-xxl-50 { opacity: .5 !important; }
.opacity-xxl-75 { opacity: .75 !important; }
.opacity-xxl-100 { opacity: 1 !important; }
}
print 옵션을 활성화하면 @media print { ... } 미디어 쿼리 안에서만 적용되는 print용 유틸리티 클래스도 생성돼요.
$utilities: (
"opacity": (
property: opacity,
print: true,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
출력:
.opacity-0 { opacity: 0 !important; }
.opacity-25 { opacity: .25 !important; }
.opacity-50 { opacity: .5 !important; }
.opacity-75 { opacity: .75 !important; }
.opacity-100 { opacity: 1 !important; }
@media print {
.opacity-print-0 { opacity: 0 !important; }
.opacity-print-25 { opacity: .25 !important; }
.opacity-print-50 { opacity: .5 !important; }
.opacity-print-75 { opacity: .75 !important; }
.opacity-print-100 { opacity: 1 !important; }
}
중요도 (Importance)
API로 생성된 모든 유틸리티는 컴포넌트와 수정자 클래스를 의도대로 오버라이드하도록 !important를 포함해요. 이 설정은 $enable-important-utilities 변수(기본값 true)로 전역적으로 토글할 수 있어요.
API 사용하기 (Using the API)
이제 유틸리티 API가 어떻게 동작하는지 익숙해졌으니, 자신만의 커스텀 클래스를 추가하고 기본 유틸리티를 수정하는 방법을 배워 보세요.
유틸리티 오버라이드 (Override utilities)
기존 유틸리티는 같은 키를 사용해서 오버라이드할 수 있어요. 예를 들어 추가적인 반응형 overflow 유틸리티 클래스를 원하면 이렇게 할 수 있어요:
$utilities: (
"overflow": (
responsive: true,
property: overflow,
values: visible hidden scroll auto,
),
);
유틸리티 추가 (Add utilities)
새 유틸리티는 map-merge로 기본 $utilities 맵에 추가할 수 있어요. 필수 Sass 파일과 _utilities.scss를 먼저 import했는지 확인한 다음, map-merge로 추가 유틸리티를 더하세요. 예를 들어 세 가지 값을 가진 반응형 cursor 유틸리티를 추가하는 방법이에요.
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";
$utilities: map-merge(
$utilities,
(
"cursor": (
property: cursor,
class: cursor,
responsive: true,
values: auto pointer grab,
)
)
);
@import "bootstrap/scss/utilities/api";
유틸리티 수정 (Modify utilities)
map-get과 map-merge 함수로 기본 $utilities 맵의 기존 유틸리티를 수정할 수 있어요. 아래 예시에서는 width 유틸리티에 추가 값을 더하고 있어요. 초기 map-merge로 시작한 다음 수정할 유틸리티를 지정해요. 거기서부터 map-get으로 중첩된 "width" 맵을 가져와 유틸리티의 옵션과 값에 접근하고 수정해요.
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";
$utilities: map-merge(
$utilities,
(
"width": map-merge(
map-get($utilities, "width"),
(
values: map-merge(
map-get(map-get($utilities, "width"), "values"),
(10: 10%),
),
),
),
)
);
@import "bootstrap/scss/utilities/api";
반응형 활성화 (Enable responsive)
기본적으로 반응형이 아닌 기존 유틸리티 세트에 반응형 클래스를 활성화할 수 있어요. 예를 들어 border 클래스를 반응형으로 만들려면:
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";
$utilities: map-merge(
$utilities,
(
"border": map-merge(
map-get($utilities, "border"),
( responsive: true ),
),
)
);
@import "bootstrap/scss/utilities/api";
이제 각 브레이크포인트에 대해 .border와 .border-0의 반응형 변형이 생성될 거예요. 생성된 CSS는 이렇게 보일 거예요:
.border { ... }
.border-0 { ... }
@media (min-width: 576px) {
.border-sm { ... }
.border-sm-0 { ... }
}
@media (min-width: 768px) {
.border-md { ... }
.border-md-0 { ... }
}
@media (min-width: 992px) {
.border-lg { ... }
.border-lg-0 { ... }
}
@media (min-width: 1200px) {
.border-xl { ... }
.border-xl-0 { ... }
}
@media (min-width: 1400px) {
.border-xxl { ... }
.border-xxl-0 { ... }
}
유틸리티 이름 바꾸기 (Rename utilities)
v4 유틸리티가 빠져 있거나 다른 명명 규칙에 익숙한가요? 유틸리티 API를 사용해 주어진 유틸리티의 결과 클래스를 오버라이드할 수 있어요. 예를 들어 .ms-* 유틸리티를 예전 명명의 .ml-*로 바꾸려면:
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";
$utilities: map-merge(
$utilities,
(
"margin-start": map-merge(
map-get($utilities, "margin-start"),
( class: ml ),
),
)
);
@import "bootstrap/scss/utilities/api";
유틸리티 제거 (Remove utilities)
map-remove() Sass 함수로 기본 유틸리티를 제거할 수 있어요.
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";
// Remove multiple utilities with a comma-separated list
$utilities: map-remove($utilities, "width", "float");
@import "bootstrap/scss/utilities/api";
map-merge() Sass 함수를 사용하고 그룹 키를 null로 설정해서 유틸리티를 제거할 수도 있어요.
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";
$utilities: map-merge(
$utilities,
(
"width": null
)
);
@import "bootstrap/scss/utilities/api";
추가, 제거, 수정 (Add, remove, modify)
map-merge() Sass 함수로 한 번에 많은 유틸리티를 추가·제거·수정할 수 있어요. 이전 예시들을 하나의 더 큰 맵으로 결합하는 방법이에요.
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";
$utilities: map-merge(
$utilities,
(
// Remove the `width` utility
"width": null,
// Make an existing utility responsive
"border": map-merge(
map-get($utilities, "border"),
( responsive: true ),
),
// Add new utilities
"cursor": (
property: cursor,
class: cursor,
responsive: true,
values: auto pointer grab,
)
)
);
@import "bootstrap/scss/utilities/api";
RTL에서 유틸리티 제거 (Remove utility in RTL)
일부 경계 사례는 RTL 스타일링을 어렵게 만들어요(예: 아랍어의 줄 바꿈). 따라서 rtl 옵션을 false로 설정하면 RTL 출력에서 유틸리티를 빼버릴 수 있어요:
$utilities: (
"word-wrap": (
property: word-wrap word-break,
class: text,
values: (break: break-word),
rtl: false
),
);
출력:
/* rtl:begin:remove */
.text-break {
word-wrap: break-word !important;
word-break: break-word !important;
}
/* rtl:end:remove */
RTLCSS remove 제어 지시문 덕분에, 이 코드는 RTL에서는 아무것도 출력하지 않아요.