레이블과 완벽하게 일치하는 CSS에서 액세스 가능한 사용자 지정 라디오 및 확인란 단추를 만드는 방법을 알아 봅니다.
https://codyhouse.co/blog/post/custom-accessible-radio-checkbox-buttons-vertical-alignment
사용자 지정 라디오 / 체크 박스 버튼을 만드는 것은 쉬운 일이 아닙니다. 액세스 가능하고 사용자 정의하기 쉬우며 라벨에 완벽하게 정렬되어야 합니다.
최종 결과
다음은 최종 결과의 미리보기입니다 (CodyHouse UI 구성 요소 다운로드).
https://codepen.io/codyhouse/pen/jOqaZYK
HTML
구성 요소를 만들 때 지켜야 할 중요한 규칙은 가장 단순한 구조로 시작하여 필요한 경우에만 더 많은 요소 (예 : 상위 래핑)를 추가하는 것입니다.
라디오 및 확인란 버튼의 경우 다음이 모두 필요합니다.
<!-- radio button --> <div> <input class="radio" type="radio" name="radio-button" id="radio-1"> <label for="radio-1">Choice 1</label> </div> <!-- checkbox button --> <div> <input class="checkbox" type="checkbox" id="checkbox-1"> <label for="checkbox-1">Option 1</label> </div>
HTML 구조는 입력에 .radio / .checkbox 클래스를 추가한다는 점을 제외하면 기본 버튼과 함께 사용하는 구조와 동일합니다.
CSS
1 단계는 네이티브 버튼을 시각적으로 숨기는 것입니다.
// hide native buttons .radio, .checkbox { position: absolute; margin: 0 ; padding: 0 ; opacity: 0; height: 0; width: 0; pointer-events: none; }
절대 위치 요소에 대해 위쪽 / 오른쪽 / 아래쪽 / 왼쪽 값을 설정하지 않으면 흐름에서 제거되지만 이동하지는 않습니다. 그렇지 않으면 위치를 예측할 수 없고 버튼을 클릭 할 때 페이지 상단으로 스크롤 될 수 있기 때문에 중요합니다.
다음으로 + (인접한 형제 결합 자)를 사용하여 레이블과 해당 :: before 유사 요소 (사용자 지정 단추)를 대상으로 지정하고 스타일을 지정할 것입니다.
// label .radio + label, .checkbox + label { user-select: none; cursor: pointer; line-height: 1.4; } // custom buttons - basic style .radio + label::before, .checkbox + label::before { content: ''; display: inline-block; width: 18px; height: 18px; background-color: var(--color-bg); border: 2px solid var(--color-contrast-low); margin-right: var(--space-xxxs); // gap between custom input and label transition: .2s; } // radio only style .radio + label::before { border-radius: 50%; } // checkbox only style .checkbox + label::before { border-radius: 4px; }
이 시점에서 CSS 사용자 정의 속성을 만들 수 있습니다. 이렇게 하면 나중에 버튼을 수정하기로 결정하면 커스터마이징이 훨씬 쉬워진다는 장점이 있습니다. 모든 CSS를 검사하는 대신 변수를 보고 업데이트 할 수 있습니다.
:root { // radios and checkboxes --checkbox-radio-size: 18px; --checkbox-radio-gap: var(--space-xxxs); // gap between button and label --checkbox-radio-border-width: 2px; --checkbox-radio-line-height: var(--body-line-height); // radio buttons --radio-marker-size: 8px; // checkboxes --checkbox-marker-size: 12px; --checkbox-radius: 4px; } // replace fixed values with variables - example ? .checkbox + label::before { border-radius: var(--checkbox-radius); }
입력의 확인 상태를 대상으로 지정하고 레이블 의사 요소에 스타일을 적용 할 것입니다.
// :checked .radio:checked + label::before, .checkbox:checked + label::before { background-color: var(--color-primary); border-color: var(--color-primary); } // radio button :checked .radio:checked + label::before { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cg class='nc-icon-wrapper' fill='%23ffffff'%3E%3Ccircle cx='8' cy='8' r='8' fill='%23ffffff'%3E%3C/circle%3E%3C/g%3E%3C/svg%3E"); background-size: var(--radio-marker-size); } // checkbox button :checked .checkbox:checked + label::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpolyline points='1 6.5 4 9.5 11 2.5' fill='none' stroke='%23FFFFFF' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'/%3E%3C/svg%3E"); background-size: var(--checkbox-marker-size); }
(데이터 URI를 통해) SVG 마커를 추가하기 위해 background-image 속성을 사용하고 있습니다. 이 기술의 장점은 CSS에서 아이콘의 두께 (stroke-width = '2')와 색상 (stroke = '% 23FFFFFF')을 사용자 정의 할 수 있다는 것입니다.
우리가 지금까지 가지고 있는 것 :
Alignment
가장 어려운 부분은 라디오 / 체크 박스 버튼을 라벨에 맞추는 것입니다.
먼저 레이블의 표시 속성을 inline-flex와 동일하게 설정하고 align-items는 flex-start와 동일하게 설정합니다.
:root { // ... --checkbox-radio-gap: var(--space-xxxs); --checkbox-radio-line-height: var(--body-line-height); } // label .radio + label, .checkbox + label { display: inline-flex; align-items: flex-start; // align button and label to top line-height: var(--checkbox-radio-line-height); // ... } // custom buttons - basic style .radio + label::before, .checkbox + label::before { flex-shrink: 0; // prevent the button from shrinking margin-right: var(--checkbox-radio-gap); // gap // ... }
이렇게 함으로써 레이블이 여러 줄로 나눌 때 표시되는 왼쪽 정렬 문제를 수정하고 단추와 레이블을 맨 위에 수직으로 정렬했습니다.
버튼과 레이블을 수직으로 정렬하려면 레이블의 높이를 계산해야 합니다. 이 값은 글꼴 크기에 줄 높이를 곱한 값과 같습니다.
line-height는 var (-checkbox-radio-line-height) 사용자 정의 속성에 저장됩니다. 레이블의 글꼴 크기 계산 값은 예측할 수 없지만 (예 : 유틸리티 클래스를 사용하여 변경할 수 있음) label :: before pseudo-element의 경우 font-size는 항상 1em과 동일합니다!
높이를 알면 수식을 사용하여 레이블의 첫 번째 줄에 정렬되는 매우 특정한 양의 사용자 지정 라디오 / 확인란 버튼을 누를 수 있습니다. ?
.radio + label::before, .checkbox + label::before { // .. position: relative; top: calc((1em * var(--checkbox-radio-line-height) - var(--checkbox-radio-size)) / 2); }
이 공식은 모든 글꼴 크기 및 글꼴 패밀리 값과 호환됩니다.
더 이상 캐주얼하고 예측할 수 없는 마이너스 마진 트릭이 없습니다! ?
접근성
사용자 지정 요소를 만들지 않았기 때문에 구성 요소에 액세스 할 수 있으며 화면 판독기에서 올바르게 알립니다.
그러나 : focus 효과를 포함하는 것을 잊지 마십시오 (기본 버튼은 표시되지 않음).
// :focus .radio:focus + label::before, .checkbox:focus + label::before { border-color: var(--color-primary); box-shadow: 0 0 0 3px alpha(var(--color-primary), 0.2); }
최종 결과
최종 결과입니다! 이 구성 요소는 UI 프레임 워크에서 다운로드 할 수 있습니다.
https://codepen.io/codyhouse/pen/jOqaZYK
등록된 댓글이 없습니다.