Base Styles
브라우저 기본 스타일 초기화 및 정규화를 위한 CSS 파일. reset.css와 normalize.css를 제공합니다.
디자인 시스템을 사용하기 전에 브라우저 기본 스타일을 초기화하고 일관된 기본 스타일을 적용해야 합니다.
사용 방법
Preset 사용 (권장)
Preset 하나로 Reset, Normalize, 브랜드 토큰, CSS Layer 순서가 모두 설정됩니다.
// _app.tsx, main.tsx, 또는 layout.tsx
import '@featuring-corp/components/preset/featuring';Preset은 @layer ft-reset, ft-normalize, ft-components, ft-utilities 순서를 선언하며, reset.css와 normalize.css가 각각 ft-reset, ft-normalize 레이어에 포함됩니다.
참고: 원본 CSS 파일(
reset.css,normalize.css)은@layer reset,@layer normalize를 사용합니다. Preset이 이를ft-reset,ft-normalize로 re-wrap하여 외부 레이어 시스템과 충돌 없이 사용할 수 있게 합니다.
개별 Import (고급)
Tailwind 등 자체 reset을 사용하는 프로젝트에서는 개별 import도 가능합니다.
// _app.tsx, main.tsx, 또는 layout.tsx
import '@featuring-corp/design-tokens/style/reset.css';
import '@featuring-corp/design-tokens/style/normalize.css';
import '@featuring-corp/design-tokens/style/featuring.css'; // 테마 CSS요약
reset.css
| 적용 대상 | 스타일 |
|---|---|
| 모든 HTML 요소 | margin: 0, padding: 0, border: 0 |
| 모든 HTML 요소 | font-size: 100%, font: inherit, vertical-align: baseline |
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section | display: block |
body | line-height: 1 |
ol, ul | list-style: none |
blockquote, q | quotes: none |
blockquote:before, blockquote:after, q:before, q:after | content: '', content: none |
table | border-collapse: collapse, border-spacing: 0 |
normalize.css
| 적용 대상 | 스타일 |
|---|---|
html | text-size-adjust: none |
body | margin: 0, color: var(--semantic-color-text-1) |
*, *::before, *::after, span | box-sizing: border-box |
a, button, input, select | cursor: pointer |
button, input, optgroup, select, textarea | font-family: inherit, font-size: 100%, line-height: 1.15, margin: 0 |
img | border-style: none, max-inline-size: 100%, max-block-size: 100% |
[disabled] | pointer-events: none, cursor: not-allowed |
*:focus:not(:focus-visible) | outline: none |
ol, li, ul, menu, summary | list-style: none |
table | border-collapse: collapse |
::placeholder | color: unset |
reset.css
Eric Meyer's CSS Reset v2.0 기반으로 브라우저의 모든 기본 스타일을 초기화합니다.
@featuring-corp/design-tokens/style/reset.css
@layer reset;
@layer reset {
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
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,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
}normalize.css
브라우저 간 일관된 스타일을 적용하고 기본적인 UX를 개선합니다.
@featuring-corp/design-tokens/style/normalize.css
@layer normalize;
@layer normalize {
html {
-moz-text-size-adjust: none;
-webkit-text-size-adjust: none;
text-size-adjust: none;
}
body {
margin: 0;
color: var(--semantic-color-text-1);
font-family: var(--global-typography-font-sans);
}
main {
display: block;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
pre {
font-family: monospace, monospace;
font-size: 1em;
}
a {
background-color: transparent;
}
abbr[title] {
border-bottom: none;
text-decoration: underline;
}
b,
strong {
font-weight: bolder;
}
code,
kbd,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
img {
border-style: none;
max-inline-size: 100%;
max-block-size: 100%;
}
a,
button,
input,
select {
cursor: pointer;
}
button,
input,
optgroup,
select,
textarea {
font-family: inherit;
font-size: 100%;
line-height: 1.15;
margin: 0;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
[type='button'],
[type='reset'],
[type='submit'] {
-webkit-appearance: button;
appearance: button;
}
button::-moz-focus-inner,
[type='button']::-moz-focus-inner,
[type='reset']::-moz-focus-inner,
[type='submit']::-moz-focus-inner {
border-style: none;
padding: 0;
}
button:-moz-focusring,
[type='button']:-moz-focusring,
[type='reset']:-moz-focusring,
[type='submit']:-moz-focusring {
outline: 1px dotted ButtonText;
}
fieldset {
padding: 0.35em 0.75em 0.625em;
}
legend {
box-sizing: border-box;
color: inherit;
display: table;
max-width: 100%;
padding: 0;
white-space: normal;
}
progress {
vertical-align: baseline;
}
textarea {
overflow: auto;
white-space: revert;
}
input,
textarea {
-webkit-user-select: auto;
}
[type='checkbox'],
[type='radio'] {
box-sizing: border-box;
padding: 0;
}
[type='number']::-webkit-inner-spin-button,
[type='number']::-webkit-outer-spin-button {
height: auto;
}
[type='search'] {
-webkit-appearance: textfield;
appearance: textfield;
outline-offset: -2px;
}
[type='search']::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
details {
display: block;
}
summary {
display: list-item;
}
template {
display: none;
}
[hidden] {
display: none;
}
[disabled] {
cursor: not-allowed;
}
*:focus:not(:focus-visible) {
outline: none;
}
ol,
li,
ul,
menu,
summary {
list-style: none;
}
table {
border-collapse: collapse;
}
meter {
-webkit-appearance: revert;
appearance: revert;
}
::placeholder {
color: unset;
}
*:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) {
all: unset;
display: revert;
}
:where([contenteditable]:not([contenteditable='false'])) {
-moz-user-modify: read-write;
-webkit-user-modify: read-write;
overflow-wrap: break-word;
-webkit-line-break: after-white-space;
-webkit-user-select: auto;
}
:where([draggable='true']) {
-webkit-user-drag: element;
}
:where(dialog:modal) {
all: revert;
box-sizing: border-box;
}
:where(pre) {
all: revert;
box-sizing: border-box;
}
:where([hidden]) {
display: none;
}
*,
*::before,
*::after,
span {
box-sizing: border-box;
}
/* Firefox only — Chrome 121+에서 scrollbar-color가 ::-webkit-scrollbar hover/active를 override하므로 분리 */
@supports (-moz-appearance: none) {
* {
scrollbar-width: thin;
scrollbar-color: var(--semantic-color-border-2) transparent;
}
}
/* Chrome / Safari / Edge */
::-webkit-scrollbar {
width: 8px;
height: 8px;
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: var(--semantic-color-border-2);
border-radius: var(--global-radius-100);
transition: background-color 150ms ease;
}
::-webkit-scrollbar-thumb:hover {
background-color: var(--semantic-color-border-3);
}
::-webkit-scrollbar-thumb:active {
background-color: var(--semantic-color-border-4);
}
.os-scrollbar {
--os-size: 14px !important;
--os-handle-bg: rgb(66 66 66 / 25%) !important;
--os-handle-bg-hover: var(--global-colors-gray-60) !important;
--os-padding-perpendicular: 3px !important;
}
}