CSS만 액세스할 수 있는 드롭다운 탐색 메뉴

24115 단어 webdevcssa11yhtml

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.


이 기술의 활용 방안:
  • 애니메이션 CSStransitiontransform
  • 사용:focus-within위류
  • 포지셔닝용 CSS 그리드
  • 동적중심기술
  • 드롭다운 메뉴의 액세스 가능성 고려 사항
  • 만약 당신이'스톱의도'라는 개념을 처리할 때 긴장하고 불안했었다면, 이번 업그레이드는 당신을 위해 준비한 것입니다!
    우리가 너무 멀리 가기 전에, 비록 우리의 기술은 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>는 보조 기술을 사용하여 지표
  • 를 통해 페이지를 내비게이션할 때의 용도를 확인하는 데 도움을 준다.
  • 초점을 맞출 수 있고 발견할 수 있는 요소로 하단 목록
  • 의 열기를 터치합니다
  • buttonaria-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 용기 스타일을 제공하고, 이를 격자 용기로 정의할 것이다.그런 다음 기본 목록 스타일을 navnav 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의 맨 윗부분navgrid-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 배경에서 볼 수 있다.
    이 문제는 navposition: 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 드롭다운 목록이 되도록 하는 것이다.설명에서 언급한 바와 같이 IE 를 지원해야 할 경우 polyfill가 필요합니다.현재).
    you 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: 0opacity의 조합은 다음과 같습니다.
    .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" 사용자와 함께 굴러갈 때.

    최종 결과


    마지막 결과는 화살표 하나를 포함하여 메뉴를 링크 항목에 더욱 직관적으로 연결하고 모든 내비게이션 링크의 사용자 정의 초점 상태와 navposition: sticky:

    좋은 웹페이지 즐겨찾기