NARADESIGN

웹표준, 웹접근성, 유니버설디자인, HTML, CSS, UI, UX, UD


CSS Drop Down : Emulate Select/Option.

본문 건너 뛰기

서식 제어 요소(Form Control Element)를 디자인 하는 것은 상황에 따라 접근성을 떨어뜨리는 경우가 있기 때문에 제한되어야 하고 신중하게 사용해야 합니다. 이미 이전에 포스팅을 했지만 다시 한번 환기하는 차원에서 제한되어야 하는 서식 요소들은 어떤 것들이 있는지 살펴보겠습니다.

 

스타일 변경이 제한된 서식 제어 요소들
HTML Markup View
input type="checkbox"
input type="radio"
input type="file"
input type="hidden" 화면 출력 안됨
select, option

 

서식 제어 요소의 디자인을 제한하는 이유

이런 서식 제어 요소들의 디자인을 변경하는 것은 일단 브라우저들이 지원하지 않습니다. 이런 이유 때문에 이것을 디자인 하려는 시도는 실제로는 기능하지 않는 가짜 마크업을 남발하게되고 웹 접근성을 떨어뜨리는 요인으로 작용합니다. 하나의 콘트롤을 디자인 하기 위하여 화면에 보이는 마크업과 실제로 기능을 수행하는 마크업을 각각 따로 작성하게 되면 화면낭독기 사용자들은 화면 표시를 위한 가짜 마크업 때문에 곤경에 빠지는 상황이 연출됩니다.

그리고 간혹 단순한 텍스트 링크 기능을 수행함에도 불구하고라디오 버튼을 장식적인 요소로 사용한 다음 라디오 콘트롤에 자바스크립트를 입혀서 페이지 이동을 처리하는 고품격(?) 사용자 경험을 제공하기도 하는데 매우 잘못된 방법중의 하나 입니다.

모든 서식 제어 요소들은 사용자가 ‘전송’ 버튼을 누르기 직전까지 아무짓도 하지 않고 기다려야 할 의무가 있습니다. 왜냐하면 그것이 바로 서식 제어 요소들의 올바른 사용법이고 시각 장애인들은 그런 표준화된 그리고 전통적인 사용자 인터렉션에 의지해서 웹을 탐색하고 있기 때문입니다.

"라디오 버튼을 눌렀을 뿐인데 페이지가 이동할 줄은 몰랐어요. 저는 전송 버튼을 누르지도 않았거든요."

<select> 콘트롤을 본래 목적에 맞게 사용하기

한편 서식 제어 요소를 사용할 때 사용자 입력을 전송하는데 쓰지 않았다고 해서 무조건 틀렸다고 말할 수도 없습니다. CSS가 일반적으로 널리 퍼지기 이전에 서식 제어 요소들은 다른 HTML 요소들이 흉내낼 수 없는 효과적인 UI 콘트롤을 제공했기 때문에 그 이점만을 취하기 위한 활용사례가 많았습니다. 현재까지도 흔하게 볼 수 있는 예가 바로 <select> 콘트롤 입니다. 본래의 목적은 단일 또는 다중 선택된 사용자의 선택값을 서버측에 전송하기 위한 목적이었지만 ‘패밀리 사이트 바로가기, 유관 기관으로 이동’과 같이 단순하게 텍스트 링크로 처리해도 될만한 UI에 지금까지도 여전히 <select> 요소를 사용하고 있습니다. 이 때 자바스크립트로 URL 값을 처리해서 넘기는 경우도 있고 서버측 스크립트로 값을 처리해서 넘기는 경우도 있는데 어느편이 더 유니버설한 설계 방법인지는 여러분이 직접 판단해 보시기 바랍니다.

하지만 한 발 더 나아가 저는 더 이상 <select> 콘트롤을 이용하여 페이지 이동하는 기법을 사용할 필요가 없다고 생각합니다. 자바스크립트나 서버측 스크립트를 작성해서 페이지를 이동하는 방법보다 더 쉬운 방법이 있기 때문입니다. CSS 배워서 이런데 써먹을 수 있습니다. <select> 콘트롤은 이제 그만 휴가 보내고 CSS에게 일을 시켜 보세요. <select> 요소의 드롭다운 콘트롤은 고작 ‘숨은 링크 목록’을 토글해서 보이거나 숨기는 인터렉션일 뿐입니다.

그럼에도 불구하고 <select> 콘트롤이 사랑받는 이유

요소 본래의 목적에 맞지 않는 마크업과 복잡한 스크립트의 사용을 유발함에도 불구하고 <select> 콘트롤은 여전히 기획자, 디자이너, 개발자에게 사랑받고 있습니다. 왜 그럴까요?

  • 좁은 공간을 효과적으로 사용할 수 있기 때문에
  • 클릭하면 숨은 목록을 볼 수 있는 전통적인 인터페이스로써 이미 대중에게 학습되었기 때문에
  • 오랜 세월에 걸쳐 잘 작성된 레거시 코드가 있고 새로 만들 때 복사 후 붙여넣기만 하면 되니까

정도로 요약할 수 있겠습니다. 결국 우리는 <select> 라는 콘트롤을 본래의 목적에 맞게 사용하되 ‘긴 직사각형의 우측 끝에 화살표가 달린 모양’만 취하면 되는 겁니다.

결론 : <select> 형태는 취하고 마크업은 버리자

예제를 새 창에서 보기

위의 두 예제는 같은 모양을 하고 있지만 첫 번째 예제는 링크이고 두 번째 예제는 단일 선택을 위한 폼 콘트롤 입니다. 폼 콘트롤 우측에 ‘GO’ 버튼이 보이시나요? ‘사용자가 폼을 전송하기 전까지는 아무짓도 하지 않아야 한다’는 원칙을 실천하기 위하여 존재하는 버튼 입니다. ‘GO’ 버튼이 없으면 어떻게 되냐구요? 아마도 키보드 사용자는 다른 항목을 선택할 기회를 갖지 못하고 첫 번째 항목을 선택하는 순간 이미 다른 페이지로 이동되어 있거나 또는 전송 버튼을 찾느라 곤경에 빠질 것입니다. 저 ‘GO’ 버튼이 있음으로 인해서 마우스를 사용하는 대부분의 사용자들은 불편함을 느낄 수도 있을 것입니다. 하지만 ‘누구나 사용’할 수 있도록 유니버설하게 개선되었기 때문에 ‘인류 행복의 총량’에는 큰 변화가 없을 것입니다. 

다행히도 저렇게 단일 선택 옵션이 하나만 존재하는 경우 폼 대신 첫 번째 예제와 같이 링크로 처리할 수 있는 경우가 거의 대부분 입니다. 폼 대신 링크로 처리하게 되면 ‘GO’ 버튼이 필요가 없기 때문에 모든 사람들이 더 기뻐할 것입니다. 링크 목록은 클릭하기 전까지 펼침 상태로 존재하고 Enter 키를 받아야만 페이지 이동을 하기 때문에 ‘GO’ 버튼이 없어도 키보드만으로 제어를 할 수가 있죠.

위 제시된 예제는 처리해야 할 콘텐츠가 ‘링크’ 인지 또는 ‘진짜 폼의 선택’을 위한 것인지 명확하게 이해한 다음 사용해야 합니다. 단순히 링크로 처리해야 할(처리해도 될) 항목을 두 번째 예제로 마크업 한다면 오늘 제 포스팅은 말짱 도루묵 입니다. 부디 의미와 목적에 맞는 마크업을 선택해서 사용해 주실것을 부탁 드립니다. 이번 예제도 행복한고니로부터 도움을 받았습니다. 요즈음은 행복한고니가 짬짬이 알려주는 jQuery 덕분에 아주 즐거운 나날들을 보내고 있답니다. ^^

이 밖에 더 많은 예제들이 OUIF | XEUI 페이지에 링크되어 있습니다.

분류: CSS,웹 기획,웹 디자인,웹 접근성,웹 표준,자바스크립트 | 2010년 2월 18일, 2:37 | 정찬명 | 댓글: 76개 |
트랙백URI - http://naradesign.net/wp/2010/02/18/1192/trackback/

76개의 댓글이 있습니다.

  1. 엘카 댓글:

    게시판 코딩할 때 카테고리의 select 태그에 onchange=”doChangeCategory(this); return false;” 썼는데 장애환경을 고려하지 않은 방향이었군요.
    편의와 접근성, 두마리 토끼를 취하려면 위에 나온 Anchor 태그예제를 사용해야 겠네요.
    의미상으로도 별 문제는 없겠죠?

  2. 정찬명 댓글:

    넵, 문제 없습니다. ^^

  3. 김광곤 댓글:

    웹접근성이 화두가 되기 이전에 거의 100% 사용했다고 봐도 무방한 방식이었는데…
    생각에 따라…
    기능에 따라…
    구현방식이 참 많은 듯 싶습니다…
    요즘들어 css를 사용한 DropDownBox… 가 아닌 DropDownLink를 자주
    보게되네요 ^^
    이젠 jQuery 사용 빈도도 상당히 높아진듯 싶고요…
    항상 좋은 글 감사합니다~
    그럼 수고하시고 좋은 하루 되세요~

  4. 배고픈킬러 댓글:

    상황에 따라 접근성을 떨어뜨리는 경우가 있기 때문에 제한되어야 하고 신중하게 사용해야 하기 때문에 [select] 형태를 취하되 마크업을 버리자 라고 결론을 내리셨는데요..

    각 태그의 의미와 서식태그의 올바른 사용에 대해선 동감합니다만,
    제시하신 예시는 오히려 접근성 적인 측면에서 맞지 않는 내용이 아닌가 사료됩니다.

    제시하신 예시의 경우
    첫째, [스크립트 제거] 또는 [사용 불가] 환경에서
    jQuery의 click, hover 이벤트 핸들러를 처리할 수 없기 때문에 하위메뉴 표시가 되지 않아 접근성에 위배된다고 사료됩니다.

    둘째, [키보드로만 접근] 에 대한 환경에서
    기술하신 [select] 를 사용하지 않고 구현한 예제로는 오히려 키보드로만 접근하는 사용자에 대해서는 접근을 제한시키는 역효과를 발생시킬 수 있지 않을까 생각됩니다.

    사용하지 말자 하셨던 [select] 태그의 경우
    [select]의 옵션값이 선택될 때 바로 새창 또는 페이지 이동 등의 액션을 주고 있는 등의 무분별한 사용으로 인해 Go 버튼을 추가하여 사용자의 선택에 따른 원치않는 액션을 방지하기 위하여 구현을 하는것으로 알고 있는데요..

    통상 키보드로만 이용하는 사용자 (시각장애)의 경우 tab 키 또는 음성출력 보조기구 등을 활용(가상커서 등)하여 단축키 등으로 접근을 하게 되는데, 현재 그에 대한 접근이 전혀 불가능 한것으로 보입니다. (하위 메뉴 ul의 css속성이 display:none; 으로 되어있고, 스크립트를 통해 그를 block 등으로 변경시켜 주기 때문에)

    물론 현재의 예시가 click과 hover 이벤트에 대해서만 반응하도록 구현을 하셨기에 focus 이벤트에 대해서도 감안을 하면 일반적인 사용자는 정상적으로 사용할 수 있겠지만.. 역시 첫번째에 언급했던 스크립트에 의존적이기 때문에 이 역시 접근성에 위배되는 내용이라 생각됩니다.

    이에 대한 이견이 있으시면 답글 부탁 드리겠습니다~

  5. 정낙훈 댓글:

    저는 저 div에 클릭해야 보였으면 좋겠네요.
    그냥 갖다댔을 뿐인데 내가 열려고 하지도 않은 레이어가 열리면 안되잖아요.
    나는 단지 레이어 아래의 다른 글을 클릭하려고 했는데
    저 레이어가 열림으로써 아래 글을 클릭할 수 없으면 안되잖아요.
    그래서 클릭하면 레이어가 열리는 식이면 더 좋겠어요.

  6. 아즈키 댓글:

    XE 가 처음 나왔을 때(이미 벌써 수년전이군요 :]) 찬명님께서 이 것에 대해 말씀하셨던 기억이 나네요(제로님이셨던가? ㅋㅋ 기억이 가물가물).
    아마 그때 XE 게시판의 기본 스킨에서 카테고리 선택 시 select 와 go 버튼을 나눠서 사용하셨죠.

    웹접근성이 화두가 되기 이전인 그 당시에는 참 혁신적인 부분이였습니다.
    제 기억에 그때 당시는 ‘와, 이래서 좋구나’ 하기 보다는 오히려 상이하게 바뀐 방식에 대해 불편을 호소하는 이들이 많았죠.
    ‘왜 두번 클릭으로 될 것을 세번 클릭하게 만드냐.’ 라는 이유로.. (사실 좀 불편하긴 했습니다)

    아직도 많은 사이트들에서는 카테고리를 나타내는 부분 등에서 select 가 onchange 이벤트 시 페이지 이동을 시키죠.
    찬명님께서 말씀하셨듯이 키보드 조작이 거의 불가능하다는(화살표 버튼을 누르자 마자 바로 이동해버리니까요) 엄청난 불편함이 있다는 점을 다들 알아주었으면 좋겠네요.
    개인적으로는 굳이 장애환경까지 고려하지 않더라도, 이 문제 하나만으로도 차라리 평소에 세번클릭하는 불편함을 감수하는 것이 더 나은 것 같습니다.ㅎ

    여담이지만 개인적으로는 ‘구글리더’ 에서 화면 상단에 위치하는 ‘”폴더”선택’ combo 박스가 참 마음에 듭니다. 상당히 직관적이고 편리합니다. UI 도 상당히 깔끔하고, 마우스 조작은 물론 키보드 조작도 쉬울뿐더러, 자동완성 기능도 있거든요. :]

    ps. 그런데 찬명님이 올려주신 결론 예제는 키보드로 사용불가능하네요.
    css 사용 안함으로 하면 tab 키를 사용하여 선택가능하지만, css 사용중에는 키보드로 선택이 잘 안되네요.
    마우스를 올려놓은 상태에서만 해당 element 들이 표시되기 때문인 것 같습니다.
    포커스가 간 상태에서의 동작을 추가하시거나, 키보드 이벤트를 처리해주시면 더 좋을 것 같습니다.

  7. 정찬명 댓글:

    배고픈킬러님께 답변 드립니다.

    웹 접근성은 자바스크립트 미 지원 환경을 가정하지도 않고 그것을 의미하지도 않습니다.
    자바스크립트의 겸손한 사용은 정확하게 말해서 상호운용성의 범주에 속한 개념인데 자바스크립트를 지원하지 않는 디바이스는 텍스트 전용 브라우저를 제외하고 거의 찾아보기 어렵습니다.

    텍스트 전용 브라우저를 포함해서 자바스크립트가 지원되지 않는 환경은 CSS도 함께 지원하지 않는 경우가 보통이기 때문에 딱히 CSS는 지원하는데 자바스크립트만 지원 불가능한 그런 상황을 저는 고려하지 않고 있습니다.

    물론 이 말은 자바스크립트의 무분별한 사용이 괜찮다고 말하는것은 아닙니다.

    자바스크립트 미 지원 환경을 지원하면 상호운용성이 더 좋아지는 것은 사실이기 때문에 자바스크립트 미 지원 환경에서 하위 목록을 펼침 상태로 두도록 개선을 하겠습니다.

  8. 정찬명 댓글:

    배고픈킬러님과 아즈키님께 답변 드립니다.

    모든 항목은 키보드로 접근이 됩니다. 두 번째 예제는 단일 선택을 위한 라디오 버튼으로 처리되어 있기 때문에 Tab 키로는 항목을 선택할 수 없고 방향키(↑↓)를 이용해야 합니다.

    이런 사실은 시각장애인들은 이미 알고 있고 select 콘트롤과 동일한 인터렉션이기 때문에 쉽게 알 수 있다고 생각 했습니다. 만약 제 생각이 틀렸다면 좀 더 많은 고민이 필요하겠지만 현재로서는 방향키를 사용하지 않고 Tab키 만으로 항목을 선택하려고 했던 행태를 잘 이해하지 못하고 있습니다.

    Tab키로 선택이 되지 않는다면 방향키(↑↓)를 이용해서 선택을 시도할 것이라는 제 시나리오가 잘못된 가정이었는지 의견을 더 부탁드려야 겠네요.

  9. 정찬명 댓글:

    정낙훈님,

    그렇지 않아도 처음에는 click 이었는데 마우스로 one-click을 더 줄이는 것이 효과적이라고 판단 했습니다. 의도하지 않게 하위 목록이 열린 경우 마우스를 out 시킴으로써 간단하게 실수(?)를 만회할 수 있기 때문에 치명적이지 않고 더 편리할 것이라고 생각 합니다.

    만약 제 생각과 다르시다면 hover 이벤트를 click 으로 변경해서 사용해 주세요. ^^

  10. 아즈키 댓글:

    제가 드린 말씀은 방향키를 이용해서 선택이 안되고 있다는 얘기였습니다(select 형식으로 표시되는데 tab 키로 되면 더 이상하죠, 방향키가 더 직관적입니다).

    노트북이라 키값이 잘못나와서인지도 모르겠습니다만, 제 환경 (윈도우즈 XP SP3 크롬 브라우저 4.0) 에서는 잘 안되네요.

    방향키 위아래로 안됩니다. tab 을 이용해서 포커스가 가는 것 까지는 됩니다만.

    마우스를 올린 상태에서만 목록이 보이고. 그래서 버튼 사이에 한번 더 tab 이 가능하고, 이때 tab 을 통해 radio element 로 포커스가 가게되어 방향키 조절이 가능합니다.

    즉, 키보드로 선택이 가능하나 마우스 오버가 있어야만 되는 상황인 것 같습니다.

  11. 아즈키 댓글:

    제가 현상을 설명드린 댓글을 읽어보니 저도 잘 이해가 안되네요. ㅋㅋ

    그래서 좀 더 자세한 설명.

    두번째 예제에서 보면 button 과 button 사이에 ul 과 li 와 radio 등이 있는데..

    radio 가 평소(마우스오버되지않은상태)에는 안나타납니다. ul 이 display : none 이거든요.

    그래서 radio 자체에 포커스가 애초에 갈 수가 없습니다.

    ‘옵션 button’ 에서 tab 을 누르면 바로 ‘고 button’ 으로 가죠. 마우스 오버된 상태에서만 그 사이의 radio 자체에 포커스가 갑니다.

    이게 잘 보일려나 모르겠으나, 아이폰 활용겸ㅋ 동영상을 찍어봤습니다(=뭔가 할일 없는 아즈키군요;)

    http://www.youtube.com/watch?v=6Zjla6RGqS8&feature=youtube_gdata

    방향키로 선택이 안됩니다ㅠ

  12. 정찬명 댓글:

    아즈키님,

    어떤 현상인지 알것 같습니다. 이 드롭다운 UI는 select를 흉내냈지만 키보드 경험이 완전히 일치하지는 않지요.

    진짜 select라면 콘트롤에 포커스가 맺힌 상태에서 즉시 방향키로 옵션 선택이 가능하지만
    이 드롭다운 UI는 ‘버튼 콘트롤에서 Enter 키를 입력하여 하위 목록을 펼치고 > 라디오 버튼으로 포커스를 이동시키기’ 전에는 방향키로 옵션 항목을 선택할 수가 없죠.

    저는 이 동작을 위해서 아무런 키도 자바스크립트로 맵핑하지 않았는데 키를 맵핑해 두면 불가능한 것도 아닌것 같습니다. 그러나 버튼 콘트롤에 포커스가 맺히자 마자 인위적으로 맵핑된 방향키를 사용하는 것은 시각이 있으면서 키보드를 사용하는 사용자에게 더 좋은 경험을 주지만 시각이 없이 키보드를 사용하는 사람에게는 화면낭독기 키와 충돌하거나 또는 예측 불가능한 인터렉션이 되기 때문에 사용하는데 좀 더 많은 고민이 필요하다고 생각합니다.

    키보드 동작을 글로 설명하기가 쉽지 않네요. ^^

  13. 정찬명 댓글:

    키보드 사용자가 Tab 키로 버튼 콘트롤에 focus 했을 때 하위 목록이 열리도록 할 수도 있었지만 그렇게 하지 않았습니다.

    만약 그렇게 했더라면 아마 Enter키를 눌러야 한다는 사실을 몰랐거나 귀찮아 하는 사람에게 유용할 수 있겠습니다. 그러나 키보드 사용자는 focus 만으로 어떤 내용이 보이거나 사라질 것이라는 것을 예측할 수 없고 focus만으로 맥락에 변화가 발생하는 것은 접근성에 좋지 않다고 합니다.

    이 콘트를을 이용하지 않고 단순하게 지나치거나 건너 뛰기를 원하는 사람들에게는 focus를 통해서 하위 목록이 열리는 것은 예측하지 않았던 결과이고 Tab키를 한 번 이상 더 눌러서 건너 뛰어야 하는 귀찮은 일이 될테니까요.

  14. 아즈키 댓글:

    아, 그렇군요. 키매핑은 조심해야겠네요. 크게 신경쓰지 못한 부분인데 좋은 말씀 감사합니다.

    ‘옵션 버튼’에서 space bar 키나 enter 키를 누르면 펼쳐지는 부분은 몰랐습니다(사실 프로그램적으로 보면 당연한 부분인데 말입니다).
    펼쳐진 이후에 다시 tab 을 눌러서 radio 로 포커스를 옮기고 방향키를 누르면 되는군요.

    하지만 좀 어렵습니다. 동작도 좀 많고요. 찬명님께서 저를 위해 좀 더 좋은 아이디어로 개선하시어, 널리 퍼트려주시면 감사하겠습니다. 저는 시각이 있으나, 가끔씩 키보드를 사용하고 싶거든요.

    이 방법이 옮은 방법인지는 잘 모르겠으나, ‘옵션 버튼’에 포커스가 갔을 때 펼쳐지는 동작은 어떨까요? 제 생각에는 마우스 오버시에 펼쳐지는 것보다는 포커스가 갔을 떄 펼쳐지는 것이 더 일반적이고 자연스러운 것 같습니다.
    조금 더 추가해서, ‘옵션 버튼’에 포커스가 갔을 때 목록이 펼쳐지고 그 때 포커스를 radio 로 강제 이동 시키면 키보드로 선택하기 참 편리할 것 같습니다. 다만 예상되는 문제는 radio 로 강제 이동 시킨 포커스가 다시 shift tab 버튼을 통해 돌아올 경우입니다. 다시 radio 로 강제 포커스를 이동시키기 때문에 shift tab 키 자체를 사용할 수 없으니까요. 으아, 역시 꽤 어려운 문제군요. ㅎㅎ

  15. 아즈키 댓글:

    아 제가 댓글을 남기는 동안에 다시 댓글을 주셨네요. ㅋㅋ (뭔가 시간을 넘나드는 댓글모드이네요ㅎ)

    확실히 Combo 형식이 아니라서, 포커스로 동작이 된다면, 그에 대한 사용자 경험이 좀 올바르지 바르지 못하게 될 수 있겠네요.

    Combo 형태라면 포커스가 갔다는 캐럿 표시가 text box 에서 분명하게 반짝반짝 거릴텐데말이죠.

    찬명님과 대화는 즐겁네요. :]

  16. dohoons 댓글:

    역시.. 멋진 개념글입니다^^

    마크업하기 전에 요소가 폼전송인지 단순 링크나 조작버튼인지 정확하게 파악하는게 중요하다고 생각해왔었는데 이렇게 멋지게 정리하여 글을 올려주시니 참 좋네요.

    두번째 예제 재밌네요.
    셀렉트박스 형태의 폼전송을 라디오버튼으로 마크업해서 동작시키셨군요 ㅎㅎ
    전송값 선택하는 포커스가 탭이 아니라 키보드로 해야한다는 단점이 있긴합니다만..

    그부분에 대해서 저는 select 마크업은 유지하고 스크립트로 select 를 감추고 button 요소 등을 addChild 해서 형태를 구현한 후, 스크립트로 select 요소에서 해당 값을 선택된것으로 적용시키는 방법을 생각해왔었는데..ㅎㅎ 장단점이 있는것같네요.

    결론이 잘 나왔으면 좋겠습니다 ㅋㅋ

  17. dohoons 댓글:

    이건 관계없는 내용입니다만
    블로그에 코멘트 책갈피링크를 쿼리스트링으로도 할수도 있었으면 좋겠어요 ㅠ_ㅠ
    쿼리스트링 넘어온값을 가지고 책갈피주소로 리다이렉트한다거나하는 방법으로..
    “#comment-숫자” 주소에 이런게 들어가니까 트위터에서는 해쉬태그로 인식되버리네요 킁;;

  18. 정찬명 댓글:

    저도 아즈키님과 대화하는게 즐겁습니다. 동영상까지 찍어서 올려주시고 정말 짱입니다! ㅎㅎ

  19. 정찬명 댓글:

    dohoons님,

    말씀하신 방법은 예전에 네이버에서 사용했던 방법인데 저희가 구현한 바로는 화면낭독기 사용자가 접근이 불가능 했었습니다. select 콘트롤 아닌 요소에 포커스를 가두어 놓고 방향키를 누르면 원하는 것을 보여주거나 숨은 select에서 option을 선택하도록 한 것이었는데요. 잘 못 구현해서 그랬는지 모르겠지만 저희 센터에서는 그 방법이 도저히 접근성 확보가 안되는 방법이었고 그와 관련된 고민을 저희 회사 UIT 센터에 전체 메일을 돌리기도 했었습니다. 어쨌든 최근에는 사용하지 않는 방법이 되었죠.

    제가 만든 예제가 진짜 select 콘트롤과 같은 경험을 주지 못한다는 것은 다소 아쉬운 부분이긴 한데 다른 분들이 살을 멋지게 붙여 주시면 언젠가는 가능해 질지도 모르죠.

    PS :
    # 기호는 문서 안에서 앵커 역할을 하는 표준화된 기호인데 이걸 해쉬태그로 인식하는 트위터 나빠요. ㅎㅎㅎ

  20. dohoons 댓글:

    2번 예제에서 선택된 값 표시를 버튼으로 하셔서 포커스가 생기는 바람에
    실제 값을 선택하기 까지 키보드동작이 더 필요한데 그부분은 span 또는 div 로 마크업하고

    ul 을 오픈하는 동작에 대해서 라디오버튼에 포커스 또는
    ul 에 마우스오버, 클릭 등을 통해 처리하면
    좀더 select 와 비슷한 경험을 제공할수 있을것같습니다.

  21. 아즈키 댓글:

    동영상은 할일이 없다는 것을 증명하는 ^^;

    저의 개념 부족한 댓글을 너그러이 받아주시니 감사할 따름입니다.

    저번에 올려주신 텍스트 버튼(http://naradesign.net/wp/2010/01/15/1141/). 너무나도 잘 쓰고 있습니다. 사이트가 만들어지면 인증(겸 광고?) 하겠습니다. 항상 감사합니다. :]

  22. 정찬명 댓글:

    dohoons님,
    말씀하신대로 구현이 된다면 정말 좋은 생각인것 같습니다. ^^ 구현 해주실꺼죠? ㅎㅎㅎ

  23. 정찬명 댓글:

    아즈키님, 무슨 겸손의 말씀을요. 잘 써주시면 저는 더 기분 좋습니다. 그게 저의 가장 큰 보상이자 기쁨인걸요.

  24. dohoons 댓글:

    http://dohoons.com/test/emulate/

    네…. 제 생각대로….
    라디오버튼을 이용하는것은 동일하지만
    마크업과 CSS를 수정하고 jquery 소스는 새로 해서 다시 구현해봤습니다.

    select 엘리먼트와 거의 동일한 경험을 제공하며 포커스를 시각적으로 처리했습니다.
    키보드와 마우스 접근 모두 가능하구요.
    ul 을 기본적으로 펼쳐두고 페이지가 ready 되면 hide 시키기 때문에
    자바스크립트가 꺼져 있어도 동작이 가능합니다.
    이 상태가 제일 괜찮아보이네요ㅎㅎ

    jquery 코드는 전혀 최적화 되어있지 않습니다.
    나중에 마크업이랑 CSS, 스크립트 모두 제생각대로 새로해서 라이브러리로 놔둘려구요 ㅎ

    혹시 동작에 문제있으면 알려주세요.

  25. 정찬명 댓글:

    dohoon님 잘 봤습니다. 정말 멋진데요. ^^

    포커스가 직접 라디오 버튼으로 뛰어들어가는 방법이고 키보드 접근성이나 기존 select의 경험을 그대로 살릴 수 있겠네요.

    물론 이 방법을 사용하려면 다음과 같은 추가 조치가 필요할 것 같습니다.

    1. selected 최초의 표시 값을 첫 번째 항목의 label 값과 일치 시켜야 한다.
    2. 첫 번째 항목의 값은 항상 checked=”checked” 상태여야 한다. 그렇지 않으면 선택되지 않았음에도 불구하고 “이미 이 항목이 선택 되었군” 하고 그냥 넘어갈 수 있으니까.

    dohoon님의 제안을 저도 짬날 때 코드로 반영해야 겠습니다.
    감사합니다!

  26. 정찬명 댓글:

    추가적으로 selected 상태의 label 색상은 항목을 다시 펼쳤을 때에도 인지할 수 있도록 처리해 두어야 겠네요. 제가 미처 신경쓰지 못한 부분인데 지금 발견해서 메모해 두는 겁니다. ^^

  27. dohoons 댓글:

    네 일단 말씀하신 추가조치들은 적용했습니다.
    오늘은 이만큼하고 나중에 심플하게 만들어야겠네요.
    지금 상태는 동작은 하지만
    jquery 코드가 너무 비효율적으로 돌아가서 성능문제가 심각합니다ㅋㅋㅋㅋㅋ

    그리고 표현을 위해 마크업이 바꾸는것이라는 단점까지 해결하려면
    애초에 마크업은 셀렉트박스로 하고 자바스크립트로 ready 단계에서
    DOM구조를 이와같이 바꿈으로써 구현하는게 더 좋을것같습니다.
    성능에 큰 차이가 없다면 말이죠 쩝;;

  28. 정찬명 댓글:

    앗, 지금 보니까 선택된 상태에 대한 처리를 제가 해놓고도 안했다고 메모했네요. ㅜㅜ
    성능 문제로 크리티컬한 부분이 무엇이 있는지 좀 알려주세요.
    저는 아직 자바스크립트 초보라 그런걸 좀 많이 배워야되요.
    좋은 저녁 되세요! ^^

  29. dohoons 댓글:

    일단 가장 큰건 제가 일단 jquery 로 CSS선택자를 너무 자주 사용했어요.
    그거 한번 호출때마다 계산이 많이 들어가거든요.
    가능하면 변수로 빼놓고 재활용시켜야합니다.

    구현방식도 약간만 수정하면
    UX도 지금상태에서 좀더 향상 시킬수 있을것같아서
    저도 몹시 기대하고 있습니다 ㅎ

  30. 정찬명 댓글:

    dohoons님 덕분에 잘 수정 했습니다. ^^

  31. 정찬명 댓글:

    아무래도 낙훈님 의견이 맞는것 같아서 hover 는 click 으로 변경했습니다. ^^

  32. Espressivo 댓글:

    와우 멋지네요 +_+!

  33. 정찬명 댓글:

    Espressivo님 캄사합니다. ^^

  34. 정낙훈 댓글:

    네비게이션 영역과 같이 사용이 빈번한 곳에서는 클릭 없이 하위 서브 메뉴가 뜨는 것이 나을 수 있겠으나 작은 요소에 사용되는 것은 마우스의 이동에 따라 충분히 그 곳을 거쳐갈 수도 있고 의도치 않게 다른 작업을 방해할 수도 있으니깐 클릭하는 게 나을 것 같네요. ^^;
    메뉴바 아래에 뜨는 서브메뉴도 자주 사용해서 그런지 마우스오버했을 때 그냥 서브메뉴가 좍 떠버리면 여간 귀찮은 게 아니더라고요.
    특히 메뉴가 많은 통신사 홈페이지 경우 등에서 말이죠;; 간단히 영역을 벗어날 수 있긴 하지만 가장 마우스 이동 경로가 많은 메뉴바 쪽에서 그러니 참 귀찮더라고요;;

  35. 김종호 댓글:

    정찬명님 항상 좋은 글 좋은 소스 잘 보고 갑니다.^^

    역시나 초보적인 질문이지만 이 소스를 좀 활용하고 싶은데 적용이 맘대로 안되네요 ㅠ.ㅠ;

    저의 웹사이트의 오른쪽 상단과 오른쪽 하단에 Drop down 메뉴가 있는데

    이 부분을 위 소스로 적용하려고 하는데 미리 정의해놓은 css 때문에 뭉쳐지네요 ㅠ.,ㅜ;

    작은 도움의 손길을…..

    아자 김연아 짱~~~

  36. 정찬명 댓글:

    @김종호
    미리 적용해두신 CSS를 다시 덮어쓰기 하는 방법으로 잘 안되시나요? 제가 뭘 어떻게 도와드릴 수 있을까요?

  37. 김종호 댓글:

    정찬명님 다른 도움을 요청하는 것은 아니구요^^

    맨 상단 클래스명을 수정하고 js파일에서도 바꿔주면 적용이 되겠죠?

    바로 실행에 옮겨봐야겠네요 ㅎㅎㅎ

    답글 감사해요~~~~ ^^

  38. 한사랑 댓글:

    인류행복의 총량이 변화하지 않는다는 말, 너무 인상 깊은데요. ㅎㅎ

    조금 다른 시각인데 기존 마우스 사용자들도 드롭다운메뉴를 키보드로 이용하곤 합니다.. 클릭은 마우스로 하되 드롭다운된 리스트가 길 경우 키보드의 방향키로 컨트롤하고 엔터를 치는 거죠.

    작성해주신 코드는 그런 컨트롤은 불가능한 것 같아요. 혹시 CSS만으로도 가능하게 만들 수가 있나요? 아니면 자바스크립트의 힘을 빌어야 하나요?

    궁금하네요.. :) 좋은 포스트 잘 읽었습니다.

  39. 정찬명 댓글:

    한사랑님 안녕하세요?

    예제는 Anchor와 Single Select Form 이라는 두 가지 형태로 나뉘어져 있는데요.
    Single Select Form UI가 말씀하신 것과 유사하게 구현되어 있습니다.

    Anchor는 일부러 그렇게 처리하지 않았는데요.
    Anchor는 각각의 링크를 탐색하는 기본 키가 Tab이기 때문에 일부러(인위적으로) 방향키 맵핑을 하지 않았습니다. (사실 거기까지 능력이 미치지 못한 탓도 있구요)

    방향키를 맵핑하게 되면 화면낭독기의 ‘다음 문장 탐색’이라는 명령과 충돌하는데 이걸 어떻게 처리해야 할지도 애매해 지는 측면이 있습니다.

    Single Select Form의 경우 HTML 코드상 radio 버튼으로 처리되어 있기 때문에 자바스크립트로 아무 키를 맵핑하지 않더라도 자연스럽게 select, option 탐색할 때와 같은 방향키로 탐색이 가능 합니다.

    따라서 첫 번째 예제와 두 번째 예제는 키보드 인터렉션이 다르게 설계되어 있습니다.
    Anchor일 때 방향키를 맵핑하는게 불가능한 것은 아니겠지만 바람직한지는 확신이 서지 않는다는 의견 입니다.

  40. River 댓글:

    항상 도움이 되는 글 감사드립니다.

    한가지 여쭤볼 문제가 있는데요.

    사파리에서는 포커스 이동이 input 으로만 이동되는 건가요?

    방식이 좀 다른듯하네요..

  41. 정찬명 댓글:

    River님, 혹시 사파리에서 Tab키가 링크에 접근되지 않는것을 궁금해 하시는 것이라면 아래 제 포스트를 참고해 주세요.

    Opera와 Safari는 왜 Tab Navigation이 안될까요?
    http://naradesign.net/wp/2008/05/15/141/

  42. 김대민 댓글:

    요즘 바빠서 정신없었는데…여기오니 많이 배워갑니다.^ ^ 늘 감사드려요..

  43. pm430 댓글:

    안녕하세요. 정찬명님 좋은글 잘 읽었습니다.^^
    근데 한가지 궁금한점이…
    Single Select Form 예제에서 키보드로는 옵션이 선택이 되는데, 마우스로는 선택이 안되는거 같네요? 선택은 되는데 값이 안변하는건지 모르겠네요?^^

  44. 정찬명 댓글:

    @pm430
    IE 에서 문제가 있었네요. 해결 해놨습니다. 제보 감사합니다. ^^

  45. 윤군 댓글:

    오랜만에 들렸습니다 ^^:
    날씨가 하루맑고 하루흐리고 그러네요…다름이 아니라 셀렉트박스 꾸미기의 마수에 빠져서
    헤어나오지 못하고 있네요…초급 수준의 저로선…jquery플러그인을 사용했는데…개발쪽에서
    벨류값이 전송안되는 오류가 있다고 그냥 일반 셀렉트 박스로 가자는데…디자인팀으로 소속된 저로서는 뒷 감당에 심히 우려되어 고난을 금치 못하고 있네요 ㅎㅎ
    사설이 길었구요…
    찬명님의 셀렉트 박스를 이용해볼까 해서 소스를 뜯어보다가…궁금한것이 생겼답니다.
    조기조..화살표 모양인데요.. 암만 찾아봐도 css상에서는 arrow엔 백그라운드도 없고 한데
    어찌 저런 화살표가 나오는지 궁금하네요…
    어떤 마법을 부리신건지 살짝 귀뜸해주시면 감사하겠습니다.

    혼자라서 외로운 윤군….올림

  46. 정찬명 댓글:

    @윤군
    그 화살표는 이미지를 사용하지 않기 위해서 빈 요소의 보더로 만든 것입니다. 아래 예제에서 CSS 보더 속성의 값을 바꾸면서 테스트 해보세요. 쉽게 만들 수 있습니다. ^^
    http://naradesign.net/open_content/quiz/triangle/

  47. 윤군 댓글:

    예 감사합니다..
    어찌 하다보니 결과물이 나오기는 했는데요~ ^^;
    css가 알다싶다가도 막히는게 생기네요 감사합니다.

  48. 마약 댓글:

    좋은 예제네요^^
    제가 구현하던 디자인셀렉트 박스 역시 js가 마크업을 생성하는 문제점을 안고 있었습니다. 그걸로 인해 발생하는 문제점을 알면서도 시도를 한 이유는 단순히, 불가능에 도전하는 괴팍한 취미 때문이구요…ㅋ
    저는 이런 전제를 갖고 출발했습니다.

    1. js가 로드되지 않으면 셀렉트를 원형 그대로 사용할 수 있다.
    2. js가 로드되면 목록태그를 이용한 콤보박스로 사용할 수 있다.

    결과적으로 실패했습니다. 마크업에 대한 고정관념이 낳은 삽질이었던것 같아요.ㅋㅋ
    우선 가장 큰 문제는 개발이 까다로워지는 것이었어요…
    찬명님의 글을 보니, 콤보박스 디자인을 굳이 셀렉트로 만들이유가 없다고 생각됐습니다.

    에고…^^;
    뻘짓했네요 ㅎㅎㅎ 원시코드 7.7kb 압박…ㄷㄷ;;; 결국 나중에는 힘들어서 GG~~!

    근데 요즘은 css퀴즈 안하세요? ㅎㅎ

  49. 정찬명 댓글:

    @마약
    결과적으로 포기하셨지만 한 번쯤 해볼만한 삽질이죠. ^^
    CSS 퀴즈 대신 제가 요즈음 왜 이렇게 정신없이 바쁘게 살고 있는지 그게 퀴즈 입니다. ㅋㅋㅋ

  50. 마약 댓글:

    @찬명님
    퇴근하시는길에 스토커 하나 붙을겁니다~ 아주 광팬이거든요 ㅎㅎ

  51. 정찬명 댓글:

    @마약
    저 오늘 야근하는데 괜찮으시겠어요? ㅋㅋㅋ

  52. 김무건 댓글:

    Drop Down Link 잘 쓰겠습니다!

  53. 정찬명 댓글:

    @김무건
    네, 즐거운 주말 되세요! ^^

  54. combel 댓글:

    안녕하세요. 드롭다운 아주 잘 사용하고 있는 한 유저입니다.
    일단 감사드리며 버그일 수 있는 부분이 있어 알려드립니다.
    심각한 것은 아니고요.. ^^;
    드롭다운 레이어가 두 줄에 걸쳐 있을 경우 윗줄의 레이어를 펼쳤을 경우
    아랫줄의 드롭다운 레이어에 가려지는 문제가 있네요. 그래서 약간 수정했어요.

    1. 펼침 시
    function show_option() {
    var layer = $(this).parents(‘div.select:first’);
    layer.css(‘z-index’, ‘3’);
    layer.toggleClass(‘open’);
    }

    2. 마우스 아웃 시
    select_root.mouseleave(function(){$(this).css(‘z-index’, ‘2’); $(this).removeClass(‘open’);});

  55. combel 댓글:

    아.. 그리고 한가지 더..
    폼 리셋 시에 기본값으로 돌아가지 않는 문제가 있네요.

  56. 정찬명 댓글:

    @combel
    레이어의 z-index 문제는 자바스크립트로 해결할 문제라고 생각하지 않고 상황에 맞게 CSS 코드를 수정해서 사용하는 방법이 더 권장할 만한 방법이라고 판단해서 그냥 두었습니다.

    form reset 하는 경우는 미처 생각하지 못했던 부분인데 코멘트 해주신 덕분에 JS 코드를 업데이트 했습니다. type 형식의 값이 reset으로 된 input 또는 button이 클릭되면 .myValue의 텍스트를 초기화 하도록 변경 했습니다. 물론 선택된 옵션도 reset이 됩니다.

    고맙습니다. ^^

  57. 나무 댓글:

    좋은 소스 잘 사용하고 있습니다. 감사합니다.
    ie에서 버그인지 셀렉트 박스의 역삼각형 부분을 클릭 하면 작동이 안되네요.

  58. 익명 댓글:

    감사합니다.
    그런데 2개 이상을 쓸때 겹쳐지니 상단에 위치한 셀렉트가 하단셀렉트에 가려지는 현상이 발생하는데요.
    .select.open { z-index:100; } 이걸 줘서 해결은 했는데 이 방법이 맞는가요?

  59. 정찬명 댓글:

    @나무
    네, IE 버그인데요. 해결 방법을 아직 찾지 못했습니다. 혹시 해결방법을 발견하시면 제보 좀 부탁드립니다. ^^

  60. 정찬명 댓글:

    @익명
    네, 좋은 방법인것 같습니다. 한편 이 방법은 select 요소와 select 요소 사이에 position:relative 처리된 부모 요소가 없을 때에만 사용할 수 있는 방법입니다. 만약 relative 처리된 부모 요소가 select를 감싸고 있다면 select가 아닌 부모 요소의 z-index를 높여주셔야 겠지요.

  61. 나무 댓글:

    ie에서만 해결하는 방법은 을 button이나 div myValue 안에 넣으면 ie에서는 해결이 되는데 포지션 탑을 위해 핵이 필요했구요..
    이렇게 하면 대신 파폭에서는 달라져 보여서 컨티셔널 코멘트로 ie용, ie가 아닐때로 두번을 써서 임시 방편으로 넘겨버렸습니다. ㅠㅠ

  62. 정찬명 댓글:

    @나무
    조금 복잡한 선택을 하셨군요. ㅎㅎ 저는 마이너한 버그라는 생각이 들어서 솔직히 아직 해결 의욕이 생기지 않네요. ㅋㅋ

  63. 나무 댓글:

    급해서 js를 대충 보고 넘겨서 그랬었는데요…혹시나 해서 그냥 $(‘span.ctrl’).click(show_option); 추가하니 됩니다. ㅠㅠ

  64. 정찬명 댓글:

    @나무
    좋은 선택인것 같아요. 팁을 주셔서 감사합니다. ^^

  65. Y 댓글:

    뒤늦은 질문인거 같은데 혹시나 해서 여쭤봐요.

    리스트 항목이 30개가까이 되는데요, 모두 펼쳐지게하면 너무 길어져서
    .select.open ul.aList에 height값을 넣어줬는데 마우스커서로 스크롤제어가 되지 않는 현상이 일어나는데…. 혹시 짚어주실 수 있나 해서요T_T

  66. 정찬명 댓글:

    @Y
    설명만 듣고 문제가 무엇인지 알기 어렵습니다. 문제상황을 확인할 수 있는 URL을 남겨주시면 한번 확인해 보도록 하겠습니다. 그리고 어떤 브라우저에서 발생하는 문제인지도 알려주세요.

  67. Y 댓글:

    http://bluefaith.kr/select/select.html
    보시면.. 휠 제어는 가능한데, 스크롤바 부분에 마우스 포인터를 갖다대면 펼쳐진 리스트가 사라지네요. 혹시 제가 잘못 수정한건지 해서요T_T

  68. 정찬명 댓글:

    @Y
    IE 브라우저에서만 발생하는 버그로 확인 했습니다. 이 문제를 해결하려면 아래 코드 부분을 주석으로 처리하면 됩니다.

    // Anchor Focus Out
    $(‘*:not(“div.select a”)’).focus(function(){
    $(‘.aList’).parent(‘.select’).removeClass(‘open’);
    });

    이 코드를 주석처리하면 키보드 사용자가 셀렉트 링크를 벗어났을 때 레이어가 닫히지 않는 문제가 발생합니다. 키보드 사용자가 링크를 벗어났을 때 레이어가 닫히도록 하는 코드는 직접 작성해 보세요. 저는 아직 이 문제를 어떻게 해결할지 답을 찾지 못했습니다.

  69. 김진영 댓글:

    아..
    정말 완전 감동했습니다.

    코딩하면서 셀렉트 메뉴때문에 고생하고있었거든요.
    다른곳에서 위치가 절대값인 셀렉트 메뉴를 가져와서 쓰다가
    메뉴를 넣을때마다 위치를 조정하는 눈물겨운 작업을 하고 있었어요

    원래는 다른거 찾아보려고 왔다가 목록에서 제목을 발견하고
    들어와서 보고는 감동받았습니다.

    이걸로 고치고 나니 문제가 다 해결되었어요
    ㅠㅠ

    천재이신가봐요 흑

  70. 김기현 댓글:

    코딩할때 항상 select 디자인 문제로 이견이 많은데…. 너무 좋은글이네요..

    http://naradesign.net/ouif/uio/select/xhtml.html

    이것은 ie9에서도 제대로 동작할까요? ie테스터 상에선 안돼고 있는거 같아서요..

  71. 김기현 댓글:

    실제 IE9에서도 잘되고 있네요 ^^ ie테스터만 믿을게 못되네요

  72. 박지현 댓글:

    출처 밝히며 좋은글 퍼갑니다. 문제 있을시 자삭하겠으니 알려주세요.

    http://blog.naver.com/lyaongl

  73. 댓글:

    스크롤 생기는 거랑 선택하는 거까지 여기 댓글보고 겨우 수정했는데 문제가 생겼습니다. 스크롤 때문에 높이를 3개 항목 사이즈로 지정해 놨더니 2개 항목만 넣을 때 하단이 비어버리는 현상이 생겼습니다.

    높이를 고정적으로 지정하는 게 아니라 항목 갯수에 따라 유동적으로 움직일 수 있게 할 수 있는 방법은 없을까요? 거기에 항목을 선택했더니 다시 스크롤이 선택이 안되더라구요. 쓰고 싶은데 계속 문제가 생겨서 아우…..답답하네요. j쿼리 아는 사람이 거의 없어서 SOS칠 수 있는 곳이 여기밖에 없네요.

  74. 정찬명 댓글:

    @샬
    저는 스크롤이 생기도록 하거나 또는 높이를 고정하는 방식으로 구현해 놓지 않았습니다. 다른 분의 예제를 사용하셨거나 수정된 예제를 사용하신 모양이네요.

  75. 김지원 댓글:

    셀렉트박스가 세로로 있을때, 안의 리스트가 5~6개로 넘어가면 그 내용이 셀렉트박스 밑으로 들어갑니다.z-index도 안먹히고요~

  76. 정찬명 댓글:

    @김지원
    z-index 속성을 .select 클래스가 포함된 부모 요소에 주어야 합니다.

댓글 쓰기

전송된 글이 나타나지 않는다면 필터링 된 것입니다. dece24앳gmail.com 으로 메일 주세요.
(X)HTML 코드 사용이 가능하지만 소스 코드 출력을 원하시면 <꺽쇠>는 [괄호]로 변환하여 작성해 주세요.

필수 아님

필수 아님