색상 적응형, 반응형, 접근성 있는 <button>
구성요소를 빌드하는 방법에 관한 기본 개요입니다.
이 게시물에서는 색상 적응형, 반응형, 접근성 있는 <button>
요소를 빌드하는 방법에 관한 생각을 공유하고자 합니다.
데모 사용해 보기 및 소스 보기
동영상을 선호하는 경우 이 게시물의 YouTube 버전을 확인하세요.
개요
<button>
요소는 사용자 상호작용을 위해 빌드됩니다. click
이벤트는 키보드, 마우스, 터치, 음성 등에서 타이밍에 관한 스마트 규칙을 사용하여 트리거됩니다. 또한 각 브라우저에 기본 스타일이 제공되므로 맞춤설정 없이 바로 사용할 수 있습니다. color-scheme
를 사용하여 브라우저에서 제공하는 밝은 버튼 및 어두운 버튼도 선택합니다.
다양한 유형의 버튼도 있으며 각각은 위의 Codepen 삽입에 표시되어 있습니다. 유형이 없는 <button>
은 <form>
내에 있도록 조정되어 제출 유형으로 변경됩니다.
<!-- buttons -->
<button></button>
<button type="submit"></button>
<button type="button"></button>
<button type="reset"></button>
<!-- button state -->
<button disabled></button>
<!-- input buttons -->
<input type="button" />
<input type="file">
이번 달의 GUI 챌린지에서는 의도를 시각적으로 차별화하는 데 도움이 되는 스타일을 각 버튼에 적용합니다. 재설정 버튼은 파괴적이므로 경고 색상이 사용되고 제출 버튼은 파란색 강조 텍스트가 사용되어 일반 버튼보다 약간 더 강조된 것처럼 보입니다.
버튼에는 CSS가 스타일 지정에 사용할 수 있는 의사 클래스도 있습니다. 이 클래스는 버튼의 느낌을 맞춤설정하는 CSS 후크를 제공합니다. :hover
은 마우스가 버튼 위에 있을 때, :active
는 마우스나 키보드를 누를 때를, :focus
또는 :focus-visible
은 보조 기술 스타일 지정을 지원합니다.
button:hover {}
button:active {}
button:focus {}
button:focus-visible {}
마크업
HTML 사양에서 제공하는 버튼 유형 외에도 아이콘이 있는 버튼과 맞춤 클래스 btn-custom
가 있는 버튼을 추가했습니다.
<button>Default</button>
<input type="button" value="<input>"/>
<button>
<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
<path d="..." />
</svg>
Icon
</button>
<button type="submit">Submit</button>
<button type="button">Type Button</button>
<button type="reset">Reset</button>
<button disabled>Disabled</button>
<button class="btn-custom">Custom</button>
<input type="file">
그런 다음 테스트를 위해 각 버튼을 양식 안에 배치합니다. 이렇게 하면 제출 버튼으로 작동하는 기본 버튼에 맞게 스타일이 적절하게 업데이트됩니다. 또한 아이콘 전략을 인라인 SVG에서 마스킹된 SVG로 전환하여 둘 다 동일하게 작동하도록 합니다.
<form>
<button>Default</button>
<input type="button" value="<input>"/>
<button>Icon <span data-icon="cloud"></span></button>
<button type="submit">Submit</button>
<button type="button">Type Button</button>
<button type="reset">Reset</button>
<button disabled>Disabled</button>
<button class="btn-custom btn-large" type="button">Large Custom</button>
<input type="file">
</form>
이 시점에서는 조합 매트릭스가 상당히 압도적입니다. 버튼 유형, 가상 클래스, 양식 내부 또는 외부 등 20가지가 넘는 버튼 조합이 있습니다. CSS를 사용하면 각 요소를 명확하게 설명할 수 있습니다.
접근성
버튼 요소는 자연스럽게 액세스할 수 있지만 몇 가지 일반적인 개선사항이 있습니다.
함께 마우스 오버 및 포커스 설정
:hover
및 :focus
를 :is()
기능별 의사 선택기와 함께 그룹화하려고 합니다. 이렇게 하면 인터페이스에서 항상 키보드 및 보조 기술 스타일을 고려할 수 있습니다.
button:is(:hover, :focus) {
…
}
대화형 초점 링
키보드 및 보조 기술 사용자를 위해 포커스 링에 애니메이션을 적용하고 싶습니다. 이를 위해 버튼이 활성화되지 않은 경우에만 윤곽선을 버튼에서 5픽셀 멀리 애니메이션 처리합니다. 이렇게 하면 누르면 포커스 링이 버튼 크기로 다시 축소되는 효과가 만들어집니다.
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
색상 대비 통과 확인
밝은 색상과 어두운 색상 간에 색상 대비를 고려해야 하는 색상 조합은 버튼, 제출 버튼, 재설정 버튼, 사용 중지된 버튼 등 4가지 이상입니다. 여기에서는 VisBug를 사용하여 모든 점수를 한 번에 검사하고 표시합니다.
볼 수 없는 사용자에게 아이콘 숨기기
아이콘 버튼을 만들 때 아이콘은 버튼 텍스트를 시각적으로 지원해야 합니다. 또한 이 아이콘은 시각 장애인에게는 유용하지 않습니다. 다행히 브라우저에서는 시각 장애가 있는 사용자가 장식용 버튼 이미지로 인해 방해받지 않도록 스크린 리더 기술에서 항목을 숨기는 방법을 제공합니다.
<button>
<svg … aria-hidden="true">...</svg>
Icon Button
</button>
스타일
다음 섹션에서는 먼저 버튼의 적응형 스타일을 관리하기 위한 맞춤 속성 시스템을 설정합니다. 이러한 맞춤 속성을 사용하여 요소를 선택하고 모양을 맞춤설정할 수 있습니다.
적응형 맞춤 속성 전략
이 GUI 챌린지에서 사용된 맞춤 속성 전략은 색 구성표 빌드에 사용된 전략과 매우 유사합니다. 밝은 색상과 어두운 색상 자동 조절 시스템의 경우 각 테마의 맞춤 속성이 정의되고 적절하게 이름이 지정됩니다. 그런 다음 단일 맞춤 속성이 테마의 현재 값을 보유하는 데 사용되며 CSS 속성에 할당됩니다. 나중에 단일 맞춤 속성을 다른 값으로 업데이트한 후 버튼 스타일을 업데이트할 수 있습니다.
button {
--_bg-light: white;
--_bg-dark: black;
--_bg: var(--_bg-light);
background-color: var(--_bg);
}
@media (prefers-color-scheme: dark) {
button {
--_bg: var(--_bg-dark);
}
}
밝은 테마와 어두운 테마가 선언적이고 명확한 것이 마음에 듭니다. 간접 참조 및 추상화는 이제 유일한 '반응형' 속성인 --_bg
맞춤 속성으로 오프로드됩니다. --_bg-light
및 --_bg-dark
는 정적입니다. 또한 밝은 테마가 기본 테마이고 어두운 테마는 조건부로만 적용된다는 것도 명확하게 알 수 있습니다.
디자인 일관성 준비
공유 선택기
다음 선택기는 다양한 유형의 모든 버튼을 타겟팅하는 데 사용되며 처음에는 약간 부담스럽습니다. :where()
가 사용되므로 버튼을 맞춤설정할 때는 구체적인 사항이 필요하지 않습니다. 버튼은 대체 시나리오에 맞게 조정되는 경우가 많으며 :where()
선택기를 사용하면 이 작업이 간편해집니다. :where()
내에서 각 버튼 유형이 선택됩니다. 여기에는 :is()
또는 :where()
내에서 사용할 수 없는 ::file-selector-button
도 포함됩니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
…
}
모든 맞춤 속성의 범위는 이 선택기 내에 있습니다. 이제 모든 맞춤 속성을 검토할 시간입니다. 이 버튼에는 사용되는 맞춤 속성이 꽤 많습니다. 진행하면서 각 그룹을 설명한 후 섹션 끝에 어둡고 감소된 모션 컨텍스트를 공유하겠습니다.
버튼 강조 색상
제출 버튼과 아이콘은 색상을 강조하는 데 적합합니다.
--_accent-light: hsl(210 100% 40%);
--_accent-dark: hsl(210 50% 70%);
--_accent: var(--_accent-light);
버튼 텍스트 색상
버튼 텍스트 색상은 흰색이나 검은색이 아니라 hsl()
를 사용하고 색조 210
를 고수하여 --_accent
을 어둡게 또는 밝게 조정한 버전입니다.
--_text-light: hsl(210 10% 30%);
--_text-dark: hsl(210 5% 95%);
--_text: var(--_text-light);
버튼 배경 색상
버튼 배경은 밝은 테마 버튼을 제외하고 동일한 hsl()
패턴을 따릅니다. 밝은 테마 버튼은 표시 경로가 사용자와 가까워 보이거나 다른 노출 영역 앞에 표시되도록 흰색으로 설정됩니다.
--_bg-light: hsl(0 0% 100%);
--_bg-dark: hsl(210 9% 31%);
--_bg: var(--_bg-light);
버튼 배경 우물
이 배경 색상은 노출 영역이 다른 노출 영역 뒤에 표시되도록 하기 위한 것이며 파일 입력의 배경에 유용합니다.
--_input-well-light: hsl(210 16% 87%);
--_input-well-dark: hsl(204 10% 10%);
--_input-well: var(--_input-well-light);
버튼 패딩
버튼의 텍스트 주위의 간격은 글꼴 크기와 상대적인 길이인 ch
단위를 사용합니다. 이는 큰 버튼이 font-size
를 간단히 상승시킬 수 있고 버튼이 비례적으로 확장될 때 중요합니다.
--_padding-inline: 1.75ch;
--_padding-block: .75ch;
버튼 테두리
파일 입력이 다른 버튼과 일치할 수 있도록 버튼 테두리 반경이 맞춤 속성에 저장됩니다. 테두리 색상은 기존의 적응형 색상 시스템을 따릅니다.
--_border-radius: .5ch;
--_border-light: hsl(210 14% 89%);
--_border-dark: var(--_bg-dark);
--_border: var(--_border-light);
버튼 마우스 오버 강조 표시 효과
이러한 속성은 상호작용 시 전환을 위한 크기 속성을 설정하며 강조 표시 색상은 적응형 색상 시스템을 따릅니다. 이러한 상호작용 방식은 이 게시물 뒷부분에서 다루겠지만 궁극적으로 box-shadow
효과에 사용됩니다.
--_highlight-size: 0;
--_highlight-light: hsl(210 10% 71% / 25%);
--_highlight-dark: hsl(210 10% 5% / 25%);
--_highlight: var(--_highlight-light);
버튼 텍스트 음영
각 버튼에는 은은한 텍스트 그림자 스타일이 있습니다. 이렇게 하면 텍스트가 버튼 위에 배치되어 가독성이 개선되고 깔끔한 프레젠테이션이 완성됩니다.
--_ink-shadow-light: 0 1px 0 var(--_border-light);
--_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%);
--_ink-shadow: var(--_ink-shadow-light);
버튼 아이콘
아이콘은 상대 길이 ch
단위를 사용하여 다시 2자 크기가 되므로 아이콘이 버튼 텍스트에 비례하여 크기 조절됩니다. 아이콘 색상은 적응형 및 테마 내 색상을 위해 --_accent-color
를 사용합니다.
--_icon-size: 2ch;
--_icon-color: var(--_accent);
버튼 그림자
그림자가 밝은 부분과 어두운 부분에 적절하게 조정되려면 색상과 불투명도를 모두 변경해야 합니다. 밝은 테마 그림자는 섬세하고 겹쳐지는 노출 영역 색상으로 색조가 지정된 것이 가장 좋습니다. 어두운 테마 그림자는 더 어둡고 채도가 높아야 더 어두운 노출 영역 색상을 오버레이할 수 있습니다.
--_shadow-color-light: 220 3% 15%;
--_shadow-color-dark: 220 40% 2%;
--_shadow-color: var(--_shadow-color-light);
--_shadow-strength-light: 1%;
--_shadow-strength-dark: 25%;
--_shadow-strength: var(--_shadow-strength-light);
적응형 색상과 강도를 사용하면 두 가지 그림자 깊이를 조합할 수 있습니다.
--_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%));
--_shadow-2:
0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)),
0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%));
또한 버튼에 약간 3D 모양을 제공하기 위해 1px
상자 그림자가 착시 효과를 만듭니다.
--_shadow-depth-light: 0 1px var(--_border-light);
--_shadow-depth-dark: 0 1px var(--_bg-dark);
--_shadow-depth: var(--_shadow-depth-light);
버튼 전환
적응형 색상의 패턴에 따라 디자인 시스템 옵션을 보유할 두 가지 정적 속성을 만듭니다.
--_transition-motion-reduce: ;
--_transition-motion-ok:
box-shadow 145ms ease,
outline-offset 145ms ease
;
--_transition: var(--_transition-motion-reduce);
선택기에 모든 속성 함께 표시
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
--_accent-light: hsl(210 100% 40%);
--_accent-dark: hsl(210 50% 70%);
--_accent: var(--_accent-light);--_text-light: hsl(210 10% 30%);
--_text-dark: hsl(210 5% 95%);
--_text: var(--_text-light);--_bg-light: hsl(0 0% 100%);
--_bg-dark: hsl(210 9% 31%);
--_bg: var(--_bg-light);--_input-well-light: hsl(210 16% 87%);
--_input-well-dark: hsl(204 10% 10%);
--_input-well: var(--_input-well-light);--_padding-inline: 1.75ch;
--_padding-block: .75ch;--_border-radius: .5ch;
--_border-light: hsl(210 14% 89%);
--_border-dark: var(--_bg-dark);
--_border: var(--_border-light);--_highlight-size: 0;
--_highlight-light: hsl(210 10% 71% / 25%);
--_highlight-dark: hsl(210 10% 5% / 25%);
--_highlight: var(--_highlight-light);--_ink-shadow-light: 0 1px 0 hsl(210 14% 89%);
--_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%);
--_ink-shadow: var(--_ink-shadow-light);--_icon-size: 2ch;
--_icon-color-light: var(--_accent-light);
--_icon-color-dark: var(--_accent-dark);
--_icon-color: var(--accent, var(--_icon-color-light));--_shadow-color-light: 220 3% 15%;
--_shadow-color-dark: 220 40% 2%;
--_shadow-color: var(--_shadow-color-light);
--_shadow-strength-light: 1%;
--_shadow-strength-dark: 25%;
--_shadow-strength: var(--_shadow-strength-light);
--_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%));
--_shadow-2:
0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)),
0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%))
;--_shadow-depth-light: hsl(210 14% 89%);
--_shadow-depth-dark: var(--_bg-dark);
--_shadow-depth: var(--_shadow-depth-light);--_transition-motion-reduce: ;
--_transition-motion-ok:
box-shadow 145ms ease,
outline-offset 145ms ease
;
--_transition: var(--_transition-motion-reduce);
}
어두운 테마 조정
어두운 테마 속성이 설정되면 -light
및 -dark
정적 속성 패턴의 값이 명확해집니다.
@media (prefers-color-scheme: dark) {
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
--_bg: var(--_bg-dark);
--_text: var(--_text-dark);
--_border: var(--_border-dark);
--_accent: var(--_accent-dark);
--_highlight: var(--_highlight-dark);
--_input-well: var(--_input-well-dark);
--_ink-shadow: var(--_ink-shadow-dark);
--_shadow-depth: var(--_shadow-depth-dark);
--_shadow-color: var(--_shadow-color-dark);
--_shadow-strength: var(--_shadow-strength-dark);
}
}
이렇게 하면 읽기 쉬울 뿐만 아니라 이러한 맞춤 버튼의 소비자는 사용자 환경설정에 적절하게 조정될 것이라는 확신을 가지고 빈 속성을 사용할 수 있습니다.
모션 적응 감소
방문한 사용자가 모션을 허용하는 경우 --_transition
를 var(--_transition-motion-ok)
에 할당합니다.
@media (prefers-reduced-motion: no-preference) {
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
--_transition: var(--_transition-motion-ok);
}
}
몇 가지 공유 스타일
버튼과 입력은 페이지 글꼴의 나머지 부분과 일치하도록 글꼴이 inherit
로 설정되어야 합니다. 그러지 않으면 브라우저에 의해 스타일이 지정됩니다. 이는 letter-spacing
에도 적용됩니다. line-height
를 1.5
로 설정하면 문자 상자 크기가 위아래에 여백이 있도록 설정됩니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
/* …CSS variables */
font: inherit;
letter-spacing: inherit;
line-height: 1.5;
border-radius: var(--_border-radius);
}
버튼 스타일 지정
선택기 조정
선택기 input[type="file"]
는 입력의 버튼 부분이 아니고 유사 요소 ::file-selector-button
가 있으므로 목록에서 input[type="file"]
를 삭제했습니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="file"]
),
:where(input[type="file"])::file-selector-button {
}
커서 및 터치 조정
먼저 커서 스타일을 pointer
스타일로 지정합니다. 이렇게 하면 버튼이 마우스 사용자에게 양방향임을 나타낼 수 있습니다. 그런 다음 touch-action: manipulation
를 추가하여 클릭이 기다릴 필요가 없고 잠재적인 더블클릭을 관찰하지 않도록 하여 버튼이 더 빠르게 느껴지도록 합니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
cursor: pointer;
touch-action: manipulation;
}
색상 및 테두리
그런 다음 앞서 설정한 일부 적응형 맞춤 속성을 사용하여 글꼴 크기, 배경, 텍스트, 테두리 색상을 맞춤설정합니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
font-size: var(--_size, 1rem);
font-weight: 700;
background: var(--_bg);
color: var(--_text);
border: 2px solid var(--_border);
}
그림자
버튼에 몇 가지 멋진 기법이 적용되어 있습니다. text-shadow
는 밝은 색상과 어두운 색상에 맞게 조정되므로 배경 위에 멋지게 배치된 버튼 텍스트가 눈에 잘 띄지 않고도 눈에 띄게 표시됩니다. box-shadow
에는 그림자가 3개 할당됩니다. 첫 번째(--_shadow-2
)는 일반 박스 그림자입니다.
두 번째 그림자는 버튼이 약간 위아래로 보이게 하는 눈의 묘기입니다. 마지막 그림자는 마우스 오버 강조 표시용으로, 처음에는 크기가 0이지만 나중에 크기가 지정되고 버튼에서 커지는 것처럼 보이도록 전환됩니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
box-shadow:
var(--_shadow-2),
var(--_shadow-depth),
0 0 0 var(--_highlight-size) var(--_highlight)
;
text-shadow: var(--_ink-shadow);
}
레이아웃
버튼에 플렉스박스 레이아웃, 특히 콘텐츠에 맞는 inline-flex
레이아웃을 적용했습니다. 그런 다음 텍스트를 가운데에 배치하고 하위 요소를 세로 및 가로로 중앙에 정렬합니다. 이렇게 하면 아이콘과 기타 버튼 요소가 올바르게 정렬됩니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
display: inline-flex;
justify-content: center;
align-items: center;
text-align: center;
}
간격
버튼 간격의 경우 gap
를 사용하여 상위 요소가 서로 닿지 않도록 하고 패딩에 논리적 속성을 사용하여 버튼 간격이 모든 텍스트 레이아웃에 적용되도록 했습니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
gap: 1ch;
padding-block: var(--_padding-block);
padding-inline: var(--_padding-inline);
}
터치 및 마우스 UX
다음 섹션은 주로 휴대기기를 사용하는 터치 사용자를 위한 것입니다. 첫 번째 속성인 user-select
는 모든 사용자에게 적용되며, 버튼 텍스트를 강조 표시하는 텍스트를 방지합니다. 이는 버튼을 탭하고 길게 누르고 운영체제가 버튼의 텍스트를 강조 표시할 때 터치 기기에서 주로 눈에 띕니다.
일반적으로 이 기능은 내장 앱의 버튼이 있는 사용자 환경이 아니라는 것을 알았으므로 user-select
를 none으로 설정하여 사용 중지합니다. 탭 강조 표시 색상(-webkit-tap-highlight-color
) 및 운영체제 컨텍스트 메뉴(-webkit-touch-callout
)는 일반적인 버튼 사용자의 기대치에 부합하지 않는 매우 웹 중심의 버튼 기능이므로 이를 삭제합니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
user-select: none;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
}
화면전환
적응형 --_transition
변수는 전환 속성에 할당됩니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
…
transition: var(--_transition);
}
사용자가 실제로 누르지 않은 상태에서 마우스를 가져가면 버튼 내부에서 커지는 듯한 멋진 포커스 모양을 만들기 위해 그림자 강조 표시 크기를 조정합니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
):where(:not(:active):hover) {
--_highlight-size: .5rem;
}
포커스가 있을 때 버튼에서 포커스 윤곽선 오프셋을 늘려 버튼 내부에서 커지는 것처럼 보이는 멋진 포커스 모양을 만듭니다.
:where(button, input):where(:not(:active)):focus-visible {
outline-offset: 5px;
}
아이콘
아이콘을 처리하기 위해 선택기에는 직접 SVG 하위 요소 또는 맞춤 속성 data-icon
가 있는 요소를 위한 :where()
선택기가 추가되었습니다. 아이콘 크기는 인라인 및 블록 로직 속성을 사용하여 맞춤 속성으로 설정됩니다. 획 색상과 text-shadow
에 맞는 drop-shadow
가 설정됩니다. flex-shrink
은 0
로 설정되어 아이콘이 압축되지 않습니다. 마지막으로 선이 그어진 아이콘을 선택하고 여기에 fill: none
및 round
선 끝과 선 접합을 사용하여 이러한 스타일을 할당합니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
) > :where(svg, [data-icon]) {
block-size: var(--_icon-size);
inline-size: var(--_icon-size);
stroke: var(--_icon-color);
filter: drop-shadow(var(--_ink-shadow));
flex-shrink: 0;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
}
제출 버튼 맞춤설정
제출 버튼이 약간 강조된 모양을 갖도록 하기 위해 버튼의 텍스트 색상을 강조 색상으로 지정했습니다.
:where(
[type="submit"],
form button:not([type],[disabled])
) {
--_text: var(--_accent);
}
재설정 버튼 맞춤설정
재설정 버튼에 잠재적으로 파괴적인 동작에 대한 경고 표시를 내장하여 사용자에게 알리고 싶었습니다. 또한 밝은 테마 버튼의 스타일을 어두운 테마보다 빨간색 강조 표시를 더 많이 사용하도록 선택했습니다. 적절한 밝은 색상 또는 어두운 색상의 기본 색상을 변경하여 맞춤설정할 수 있으며, 버튼을 누르면 스타일이 업데이트됩니다.
:where([type="reset"]) {
--_border-light: hsl(0 100% 83%);
--_highlight-light: hsl(0 100% 89% / 20%);
--_text-light: hsl(0 80% 50%);
--_text-dark: hsl(0 100% 89%);
}
또한 초점 윤곽선 색상이 빨간색 강조 색상과 일치하면 좋을 것이라고
생각했습니다. 텍스트 색상이 어두운 빨간색에서 밝은 빨간색으로 조정됩니다. 윤곽선 색상을 currentColor
키워드와 일치시킵니다.
:where([type="reset"]):focus-visible {
outline-color: currentColor;
}
사용 중지된 버튼 맞춤설정
사용 중지된 버튼을 덜 활성화된 것처럼 보이도록 사용 중지된 버튼의 색상 대비를 낮추려고 할 때 색상 대비가 낮은 경우가 많습니다. 각 색상 세트를 테스트하고 통과하는지 확인했으며, DevTools 또는 VisBug에서 점수가 통과할 때까지 HSL 밝기 값을 조정했습니다.
:where(
button,
input[type="button"],
input[type="submit"],
input[type="reset"]
)[disabled] {
--_bg: none;
--_text-light: hsl(210 7% 40%);
--_text-dark: hsl(210 11% 71%);
cursor: not-allowed;
box-shadow: var(--_shadow-1);
}
파일 입력 버튼 맞춤설정
파일 입력 버튼은 스팬과 버튼의 컨테이너입니다. CSS는 중첩된 버튼뿐만 아니라 입력 컨테이너에도 약간의 스타일을 지정할 수 있지만 스팬에는 지정할 수 없습니다. 컨테이너에 max-inline-size
가 주어져 필요한 것보다 더 커지지 않도록 하는 반면 inline-size: 100%
는 자체적으로 컨테이너를 실제보다 작게 축소하고 맞출 수 있도록 합니다. 배경 색상은 다른 표면보다 어두운 자동 조절 색상으로 설정되므로 파일 선택기 버튼 뒤에 표시됩니다.
:where(input[type="file"]) {
inline-size: 100%;
max-inline-size: max-content;
background-color: var(--_input-well);
}
파일 선택기 버튼과 입력 유형 버튼에는 다른 버튼 스타일로 덮어쓰지 않은 브라우저 제공 스타일을 삭제하기 위해 appearance: none
가 특별히 지정됩니다.
:where(input[type="button"]),
:where(input[type="file"])::file-selector-button {
appearance: none;
}
마지막으로 버튼의 inline-end
에 여백을 추가하여 스팬 텍스트를 버튼에서 멀리 밀어내고 공백을 만듭니다.
:where(input[type="file"])::file-selector-button {
margin-inline-end: var(--_padding-inline);
}
특별한 어두운 테마 예외
고대비 텍스트를 위해 기본 작업 버튼에 어두운 배경을 적용하여 약간 더 강조된 느낌을 주었습니다.
@media (prefers-color-scheme: dark) {
:where(
[type="submit"],
[type="reset"],
[disabled],
form button:not([type="button"])
) {
--_bg: var(--_input-well);
}
}
대안 만들기
재미와 실용성을 위해 몇 가지 변형을 만드는 방법을 보여드리기로 했습니다. 한 가지 변형은 기본 버튼의 모양과 유사하게 매우 선명합니다. 다른 변형은 큽니다. 마지막 변형에는 그라데이션으로 채워진 아이콘이 있습니다.
생생한 버튼
이 버튼 스타일을 구현하기 위해 기본 속성을 파란색으로 직접 덮어썼습니다. 빠르고 쉬웠지만 적응형 소품을 삭제하고 밝은 테마와 어두운 테마에서 모두 동일하게 보입니다.
.btn-custom {
--_bg: linear-gradient(hsl(228 94% 67%), hsl(228 81% 59%));
--_border: hsl(228 89% 63%);
--_text: hsl(228 89% 100%);
--_ink-shadow: 0 1px 0 hsl(228 57% 50%);
--_highlight: hsl(228 94% 67% / 20%);
}
큰 버튼
이 버튼 스타일은 --_size
맞춤 속성을 수정하여 구현할 수 있습니다.
패딩 및 기타 공간 요소는 이 크기를 기준으로 하며 새 크기에 비례하여 크기가 조정됩니다.
.btn-large {
--_size: 1.5rem;
}
아이콘 버튼
이 아이콘 효과는 버튼 스타일과는 아무런 관련이 없지만, 몇 가지 CSS 속성으로 이 효과를 얻는 방법과 버튼이 인라인 SVG가 아닌 아이콘을 얼마나 잘 처리하는지 보여줍니다.
[data-icon="cloud"] {
--icon-cloud: url("https://api.iconify.design/mdi:apple-icloud.svg") center / contain no-repeat;
-webkit-mask: var(--icon-cloud);
mask: var(--icon-cloud);
background: linear-gradient(to bottom, var(--_accent-dark), var(--_accent-light));
}
결론
이제 제가 어떻게 했는지 알았으니 어떻게 하시겠어요? 🙂
접근 방식을 다양화하고 웹에서 빌드하는 모든 방법을 알아보겠습니다.
데모를 만들어 트윗해 주시면 아래의 커뮤니티 리믹스 섹션에 추가해 드리겠습니다.
커뮤니티 리믹스
표시할 내용이 아직 없습니다.
리소스
- GitHub의 소스 코드