css 로 dynamically 추가되는 element 에 toggle 달기

§

튜토리얼때 골때리는 클라들 얘기하시면서 웃음을 선사하시더니 튜토리얼 끝나고 정작 본인은 이메일로 이런 질문을 주심.

질문글:

div를 check box 없이, js없이 toggle 시키는 방법 [가령 show , hide]

쉽게 이야기 하면

a 태그로 버튼을 만들었다 치고…

하나의 div 를 숨겻다 다시 펼쳣다를 시키는 기능 입니다.

다만 div는 한개만 있는게 아니라 여러개 있습니다.
물론 a 태그도 여러개 있구요.

다만 형태는 이렇습니다

<a>제목 A</a>
<div>A에 대한 이야기 </div>
<a>제목 B</a>
<div>B에 대한 이야기 </div>
<a>제목 C</a>
<div>C에 대한 이야기 </div>

패턴은 반복 입니다.
3개만 있는게 아니라 그 밑으로는 계속 늘어날 수 있는 형태 입니다.

on click 과 toggle 를 브라우저가 판단은 하니, 굳이 check box를 집어넣고 판단 한다거나. js 를 넣어서 만들지 않아도 css 만으로 가능 하지 않을까?

html 마크업이 지저분해지던가 아니면 back-end 쪽에서 출력해 줄수 있는 html 마크업 상황이 checkbox 핵을 넣어줄 수 없으니 css toggle 핵을 쓰지말고 css 만으로 toggle 을 하는 마크업을 짜달라. – 이런 요구 입니다.

이거 작년에도 모달창 관련 글 쓰면서 예제 공유/보여드렸던 건데, 뭐 이분 연세도 만만치 않으시고 보시고도 잊어버리셨을 수 있죠. ㅋㅋㅋ (조기노화로 30대에도 치매끼가 슬슬 올수도 있는거고. ㅍㅎㅎㅎ)

뭐 그것 까진 좋다 이기야. 컴 끄고 딱 자러가려다 이메일을 본거라서 빨리 마크업을 하나 작성해서 보내드렸습니다.

<style>
    #toggle1,
    #toggle2,
    #toggle3 {
      display: none;
      padding: 1em;
    }

    #toggle1:target,
    #toggle2:target,
    #toggle3:target {
      display: block;
    }

    #toggle1:target+.close,
    #toggle2:target+.close,
    #toggle3:target+.close {
      display: block;
    }

    .close {
      display: none;
    }

    .button {
      margin: 1em;
    }
  </style>


<a href="#toggle1" class="button">제목 A</a>
  <div id="toggle1">A에 대한 이야기</div>
  <a href="#닫기" class="close">제목 A 닫기</a>


  <a href="#toggle2" class="button">제목 B</a>
  <div id="toggle2">B에 대한 이야기</div>
  <a href="#닫기" class="close">제목 B 닫기</a>


  <a href="#toggle3" class="button">제목 C</a>
  <div id="toggle3">C에 대한 이야기</div>
  <a href="#닫기" class="close">제목 C 닫기</a>

그런데 오늘 다시 이메일을 보내심.

요점은 target 코딩 을 하지 않거나, 혹은 사용한다 쳐도 오직 css 만으로 자동으로 늘어나도록 하는 방법이 없을까?
하는 질문이었습니다.

아니.. 그럼 처음부터 그렇게 말을 하던가!!! 코딩 한줄 모르는 의뢰자도 아니고, 처음부터 dynamically 늘어나는 element 라고 말씀을 하시던지 나 참… ㅋㅋㅋㅋ

농담이고…. codei 님 질문은 사실 현업에서 심심치 않게 접하게 되는 문제라서 다른 front-end 개발자들에게도 유용한 내용이라 생각되어, 이런 경우 해결책을 공유해 드립니다.

일단 자스 (javascript) 로는 iterate 한번 해주면 되는거니까 어려운 문제가 아니고, codei 님도 이렇게 해결하셨는데, css 만으로 과연 이게 가능하냐는게 질문의 핵심입니다.

그리고 stackoverflow 의 수많은 답글들을 봐도 css 는 dynamically add 되는 element 에 variable 을 써서 css 를 먹여 줄수 없다는 답변만 나옵니다.

이런 얘기를 드리는 이유는, stackoverflow 는 개발자들에게 매우 좋은 resource 이지만, stackoverflow 의 답변들을 맹신/신봉 하시지 말라는 겁니다.

사실 원론적으로 따지자면 저 답변들이 틀린게 아닙니다. 상식적으로 생각해봐도 css 가 자스(javascript) 나 php 같은 프로그래밍 언어도 아니고 어떻게 생성되지도 않은 element 에 미리 css 를 먹여 줍니까? 원론적으로는 불가능 하다는 주장이 옳습니다.

그래서 지금 필요한 건? “꼼수” 입니다.

생성될 element 들을 예측해서 css 를 작성하면 dynamically 생성되는 element 에 css 를 먹일 수 있습니다.

해결 예제

<style>
    [id*="toggle"] {
     display: none;
      padding: 1em;
    }

     [id*="toggle"]:target {display: block;}

     [id*="toggle"]:target+.close {display: block;}

    .close {
      display: none;
    }

    .button {
      margin: 1em;
    }    
  </style>

 <a href="#toggle1" class="button">제목 A</a>
  <div id="toggle1">A에 대한 이야기</div>
  <a href="#닫기" class="close">제목 A 닫기</a>


  <a href="#toggle2" class="button">제목 B</a>
  <div id="toggle2">B에 대한 이야기</div>
  <a href="#닫기" class="close">제목 B 닫기</a>


  <a href="#toggle3" class="button">제목 C</a>
  <div id="toggle3">C에 대한 이야기</div>
  <a href="#닫기" class="close">제목 C 닫기</a>

출력물 보기

제가 사용한 css attribute selectors 는 유용하게/요긴하게 사용할 수 있는 경우가 많음으로, attribute selector 는 활용방법을 많이 아실수록 front-end 개발시 많은 도움이 됩니다.

Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors


*이거 사실 div 에 :focus pseudo 를 먹여서 (네, div 에 :focus 를 줄 수 없죠. 그런데 이것도 꼼수가 존재합니다) 할수 도 있을 것 같은데, 시간관계상, 나중에 시간적 여유가 있으면 이것도 한번 마크업을 짜볼 생각입니다.

div 에 tabindex 를 사용하시면 accessibility (접근성) 문제도 해결되고 :focus 도 먹일 수 있어서 참 좋은 꼼수인데, 이게 나와 있는 예제가 없어서, 제가 문서 보고

https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex

예제를 짜봐야 하거든요.

hackya 는

Attorney, front-end developer, digital media artist, WordPress enthusiast, & a father of 4 wonderful children.

Tags: , ,

카테고리: ,

Ω

Leave a Reply

Your email address will not be published. Required fields are marked *