CSS만 액세스할 수 있는 드롭다운 탐색 메뉴
This is the seventh post in a series examining modern CSS solutions to problems I've been solving over the last 13+ years of being a frontend developer. Visit ModernCSS.dev to view the whole series and additional resources.
이 기술의 활용 방안:
transition
및 transform
:focus-within
위류우리가 너무 멀리 가기 전에, 비록 우리의 기술은 100% CSS만 사용하지만, 더욱 전면적인 접근 체험을 얻기 위해 자바스크립트를 추가해야 한다.또 하나의 관건적인 특성은 polyfill이 이 기능을 실현해야 한다-
:focus-within
-for the most reliable support.그러나 시각적 효과를 실현하기 위해 jQuery 플러그인이 하나 이상 필요한 날부터 우리는 여전히 큰 개선을 했다.Accessibility update - 08/18/20: A huge thanks to of Deque (and creator of the excellent resource a11ysupport.io) for testing the original solution across various assistive technology. The CSS-only method needs some Javascript to fully meet WCAG 2.1. In particular, javascript needs to be used to offer a non-mouse/non-tab way to dismiss the menu (think escape key) to meet success criteria 1.4.13. Michael pointed to this WAI-ARIA Authoring Practices demo which provides more info on the necessary Javascript features. These are highly recommended additions for your final production solution.
만약 Sass를 사용하지 않았다면, 주어진 코드 예시를 가장 쉽게 이해하기 위해 5분 정도 걸릴 수도 있습니다.
Sass의 중첩 구문 기본 탐색 HTML
우리는 이 점을 계속 강화할 것이지만, 다음은 우리의 시작 구조이다.
<nav aria-label="Main Navigation">
<ul>
<li><a href="#">About</a></li>
<li class="dropdown">
<!-- aria-expanded needs managed with Javascript -->
<button type="button" class="dropdown__title" aria-expanded="false" aria-controls="sweets-dropdown">
Sweets
</button>
<ul class="dropdown__menu" id="sweets-dropdown">
<li><a href="#">Donuts</a></li>
<li><a href="#">Cupcakes</a></li>
<li><a href="#">Chocolate</a></li>
<li><a href="#">Bonbons</a></li>
</ul>
</li>
<li><a href="#">Order</a></li>
</ul>
</nav>
부감button
1분은 네비게이션 링크의 의미 기준이다.이런 구조는 페이지의 어느 위치에 유연하게 놓을 수 있기 때문에 메인 네비게이션처럼 사이드바의 디렉터리가 될 수 있다.Dell은 처음부터 액세스 용이성을 위한 몇 가지 기능을 구현했습니다.
aria-label
의 <nav>
는 보조 기술을 사용하여 지표button
의 aria-controls
, .dropdown__title
의 id에 연결하여 보조기술.dropdown__menu
aria-expanded
에서 최종 해결 방안에서는Javascript를 통해 전환해야 한다. 본고에서 언급한 프레젠테이션As noted by Michael, use of a
button
element also allows Dragon Naturally Speaking users to say something like 'click button' to open the menu.
기본값은 다음과 같습니다.
초기 탐색 스타일
우선, 우리는
button
용기 스타일을 제공하고, 이를 격자 용기로 정의할 것이다.그런 다음 기본 목록 스타일을 nav
및 nav ul
에서 제거합니다.nav {
background-color: #eee;
padding: 0 1rem;
display: grid;
place-items: center;
ul {
list-style: none;
margin: 0;
padding: 0;
display: grid;
li {
padding: 0;
}
}
}
우리는 이미 차원 정의를 잃었지만, 우리는 다음과 같은 내용을 통해 다시 시작할 수 있다.
nav {
// ...existing styles
> ul {
grid-auto-flow: column;
> li {
margin: 0 0.5rem;
}
}
}
서브조합 선택기nav ul li
를 사용하여 우리는 >
의 직접 서브레벨ul
의 맨 윗부분nav
을 grid-auto-flow
으로 전환하여 효과적으로 column
로 업데이트해야 한다고 정의했다.그리고 우리는 경계를 맨 윗부분 x-axis
요소에 추가하여 더 많은 정의를 얻을 것이다.현재 미래의 하단 메뉴 항목은'사탕'메뉴 아래에 나타나 하위 메뉴로 더욱 뚜렷하게 나타난다.다음은 모든 링크와
li
에 스타일을 추가한 다음에 .dropdown__title
이외의 최고급 링크만 추가합니다.이것도 우리가 .dropdown__title
요소가 계승한 본체 브라우저 스타일을 삭제한 곳이다.// Clear native browser button styles
.dropdown__title {
background-color: transparent;
border: none;
font-family: inherit;
}
nav {
> ul {
> li {
// All links contained in the li
a,
.dropdown__title {
text-decoration: none;
text-align: center;
display: inline-block;
color: blue;
font-size: 1.125rem;
}
// Only direct links contained in the li
> a,
.dropdown__title {
padding: 1rem 0.5rem;
}
}
}
}
기본 드롭다운 스타일
지금까지 우리는 원소 선택기에 의존해 왔지만, 주어진 내비게이션 목록에 여러 개가 있을 수 있기 때문에, 아래 목록을 위한 클래스 선택기를 도입할 것이다.
우선
button
링크 및 링크를 스타일링하여 위치 지정 및 애니메이션 과정에서 보다 명확하게 식별할 수 있도록 합니다..dropdown {
position: relative;
.dropdown__menu {
background-color: #fff;
border-radius: 4px;
box-shadow: 0 0.15em 0.25em rgba(black, 0.25);
padding: 0.5em 0;
min-width: 15ch;
a {
color: #444;
display: block;
padding: 0.5em;
}
}
}
그 중 뚜렷한 문제는
.dropdown__menu
용기에 영향을 주고 있다는 것이다. .dropdown__menu
용기는 아래 목록 주위의 회색 nav
배경에서 볼 수 있다.이 문제는
nav
에 position: absolute
를 추가하여 해결할 수 있으며, 이는 정상적인 문서 흐름에서 벗어날 수 있습니다.부모 목록 항목의 왼쪽과 아래에 정렬된 것을 볼 수 있습니다.설계에 따라 이상적인 위치가 될 수 있습니다.
메뉴 중심을 목록 항목에 맞추는 가운데 맞춤 기술을 제공합니다.
.dropdown__menu {
// ... existing styles
position: absolute;
// Pull up to overlap the parent list item very slightly
top: calc(100% - 0.25rem);
// Use the left from absolute position to shift the left side
left: 50%;
// Use translateX to shift the menu 50% of it's width back to the left
transform: translateX(-50%);
}
이런 퀴즈 기술의 신기한 점은 메뉴가 임의의 넓이, 심지어 동적 넓이가 될 수 있고 적당한 퀴즈를 할 수 있다는 것이다.드롭다운 디스플레이 유형
메뉴를 열려면 두 개의 주요 트리거를 사용해야 합니다.
.dropdown__menu
와 :hover
.그러나 전통적인
:focus
은 아래 목록의 열기 상태를 지속하지 않을 것이다.초기 트리거가 초점을 잃으면 키보드 초점은 밑에 있는 메뉴에서 이동할 수 있지만 시각적으로 메뉴는 사라집니다.포커스
곧
:focus-within
라는 위류가 출시될 것이다. 이것이 바로 우리가 필요로 하는 것이다. 이것이 바로 CSS 드롭다운 목록이 되도록 하는 것이다.설명에서 언급한 바와 같이 IEyou do 기울임꼴은 다음과 같은 이점을 제공합니다.
The
:focus-within
CSS pseudo-class represents an element that has received focus or contains an element that has received focus. In other words, it represents an element that is itself matched by the:focus
pseudo-class or has a descendant that is matched by:focus
.
MDN에서 기본적으로 드롭다운 목록 숨기기
드롭다운 목록을 표시하기 전에 숨겨야 하기 때문에 숨겨진 스타일을 기본 상태로 사용합니다.
당신의 첫 번째 본능은 아마도
:focus-within
일 것입니다. 그러나 이것은 우리로 하여금 과도 애니메이션을 우아하게 설정할 수 없게 합니다.다음은 원소를 뚜렷하게 숨길 수 있지만, 원소가 계산 높이를 가지고 있기 때문에 '겹침 링크' 를 남길 수 있습니다.
반면
display: none
, opacity: 0
및 opacity
의 조합은 다음과 같습니다..dropdown__menu {
// ... existing styles
transform: rotateX(-90deg) translateX(-50%);
transform-origin: top center;
opacity: 0.3;
}
우리는 불투명도를 0에 추가하지만, 나중에 더 매끄러운 효과를 얻기 위해 0까지 추가하는 것은 아닙니다.또한
transform
속성을 포함visibilty
으로 업데이트하여 3D 공간에서 메뉴를 90도 뒤로 회전합니다.높이를 제외하고는 전시에 흥미로운 과도를 효과적으로 할 수 있다.또한 transform
속성을 알 수 있습니다. 기본 수평과 수직 중심이 아닌 변환을 적용하는 점을 업데이트하기 위해 이 속성을 추가합니다.또한 의 요구를 충족시키기 위해 화면 리더 사용자에게 직관적으로 표시될 때까지 링크를 숨겨야 한다.우리는 포함
rotateX(-90deg)
을 통해 이러한 행위를 확보한다(마이클이 제공한 힌트에 다시 한 번 감사합니다!)전시하기 전에
transform-origin
속성을 추가해야 합니다.Primaryvisibility: hidden
규칙에 추가하여 포커스 켜기/끄기/끄기, 즉 "앞으로"및 "뒤로"에 모두 적용할 수 있도록 합니다..dropdown__menu {
// ... existing styles
transition: 280ms all ease-out;
}
성공 기준 1.3.2 드롭다운 목록 표시
이러한 이전 설정에 따라 오버플로우 및 포커스를 표시하는 드롭다운 목록이 간결하게 완성됩니다.
.dropdown {
// ... existing styles
&:hover,
&:focus-within {
.dropdown__menu {
opacity: 1;
transform: rotateX(0) translateX(-50%);
visibility: visible;
}
}
}
먼저 우리는 반전transition
(또는 다른 속성이 작용하지 않음)을 하고 0반전.dropdown__menu
으로 리셋한 다음에 visibilty
을 계속 rotateX
로 바꾸어 완전한 가시성을 얻는다.결과는 다음과 같습니다.
opacity
속성은 메뉴를 뒤에서 움직일 수 있지만 1
는 전체적으로 부드럽게 할 뿐이다.Once again a note that for full accessibility, there is a need for Javascript to fully handle for keyboard assistive tech events that do not always trigger
:focus
. This means some sighted keyboard users may discover the dropdown links, but without a:focus
event emitted, they will not see the dropdown menu actually open. Review the w3c demo for how to finish incorporating Javascript in this solution.
중지 의도 처리
만약 네가 이미 이 사이트에서 한동안 일했다면, 나는 아래의 내용이 너를 가게 할 수 있기를 바란다🤯
처음 드롭다운 메뉴에 대해 논의하기 시작했을 때 IE7을 위한 드롭다운 메뉴를 주로 만들었습니다.하나의 큰 프로젝트에서 몇 명의 팀원들이 비슷한 질문을 했다. "만약 내가 단지 메뉴에서 스크롤하거나 미끄러지기만 한다면, 당신은 메뉴가 나타나는 것을 막을 수 있습니까?"구글에서 내가 원하는 것을 얻기 위해 정확한 단어를 여러 번 검색한 후에 내가 최종적으로 찾은 해결 방안은 이다.
rotateX
속성을 사용하고 있기 때문에, 아주 작은 지연을 추가할 수 있습니다.이것은 일반적인 목적으로 마우스 덮개를 제어하는 드롭다운 애니메이션의 트리거를 방지합니다.한 행에 모든 변환 속성을 정의할 때 순서가 중요합니다. 순서의 두 번째 값은 지연 값으로 사용됩니다.
.dropdown__menu {
// ... existing styles
transition: 280ms all 120ms ease-out;
}
결과를 보려면 다음과 같이 하십시오.hoverIntent jQuery plugin
메뉴를 터치하기 위해 상당히 여유로운 스크롤이 필요합니다. 이것은 메뉴를 열려는 의도로 대충 추정할 수 있습니다.지연 시간이 여전히 매우 짧아서 메뉴를 열기 전에 의식하지 못했기 때문에 이것은 승리였다.
자바스크립트를 사용해서 이 점을 강화할 수 있습니다. 특히 더 파괴적인 '큰 메뉴' 를 시작하려면, 이것은 매우 즐겁습니다.
드롭다운 메뉴 표시기
정지 의도는 하나의 일이지만, 실제로는 사용자에게 추가 힌트가 필요합니다. 이 메뉴에는 추가 옵션이 있습니다.흔히 볼 수 있는 약속은 원생 선택 요소의 지시부호를 모방한 '삽입 기호' 나 '아래로 화살표' 이다.
이 점을 추가하려면
opacity
스타일을 업데이트할 것입니다.우리는 그것을 transition
용기로 정의한 다음에 .dropdown__title
요소를 만들고 이 요소는 테두리 기술로 아래 화살표를 만든다.대시inline-flex
를 사용하여 텍스트에 광학적으로 정렬합니다..dropdown {
// ... existing styles
.dropdown__title {
display: inline-flex;
align-items: center;
&:after {
content: "";
border: 0.35rem solid transparent;
border-top-color: rgba(blue, 0.45);
margin-left: 0.25em;
transform: translateY(0.15em);
}
}
}
휴대폰의 메뉴 닫기
마지막으로 자바스크립트를 사용해서 강화해야 할 수도 있습니다.
CSS에만 한정되고 비응용 프로그램 사이트에 사용할 수 있도록 주체적으로
:after
해야 합니다. 메뉴 밖의 모든 클릭이 초점을 제거하고 닫을 수 있도록 해야 합니다.이것은 좀 억지스럽다. 사용자에게 낙담할 수도 있다. 따라서 자바스크립트를 사용하여 스크롤에 숨기기를 원할 수도 있다. 특히 사용자 정의
translateY()
를 사용하여 tabindex="-1"
사용자와 함께 굴러갈 때.최종 결과
마지막 결과는 화살표 하나를 포함하여 메뉴를 링크 항목에 더욱 직관적으로 연결하고 모든 내비게이션 링크의 사용자 정의 초점 상태와
nav
의 position: sticky
:Reference
이 문제에 관하여(CSS만 액세스할 수 있는 드롭다운 탐색 메뉴), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/5t3ph/css-only-accessible-dropdown-navigation-menu-1f95텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)