요소 쿼리 및 현재 사용 방법
게시 됨: 2022-03-10잠시 물리적 구조를 생각해 보십시오. 약한 재료로 큰 건물을 짓는 경우 건물을 함께 유지하기 위해 많은 외부 지원이 필요하며 튼튼하게 유지하려면 건물을 과도하게 지어야 합니다. HTML, CSS 및 JavaScript로 웹 사이트를 구축할 때 이러한 외부 지원은 프레임워크, 플러그인, 전처리기, 트랜스파일러, 편집 도구, 패키지 관리자 및 빌드 프로세스와 같이 보일 수 있습니다.
스택의 맨 위에 또 다른 플러그인을 추가하는 대신 핵심 언어 중 하나인 CSS 를 확장하여 웹 사이트를 구축하는 자료를 강화하고 외부 지원과 도구가 덜 필요한 더 우수하고 강력한 웹 사이트를 개발할 수 있는지 궁금했습니다. 짓다.
요소 쿼리의 현재 상태
CSS 전처리기와 같은 도구를 사용하여 CSS를 약식으로 작성하여 나중에 브라우저에서 보기 전에 전체 형식으로 확장합니다. 플러그인은 영향을 미치는 요소와 함께 페이지에서 작동할 수 있지만 스타일을 적용하려면 CSS 스타일을 HTML에 직접 작성하거나 다른 CSS 규칙을 적용하는 클래스 이름을 토글합니다. 두 경우 모두 페이지가 실제로 로드되기 전에 필요한 CSS를 작성하거나 생성해야 합니다.
문제
이 방법의 문제는 최고의 플러그인이라도 사용하는 각 레이아웃에서 사용자 정의 및 구성이 필요한 경우가 많다는 것입니다. 또한 JavaScript가 스타일을 작성할 때 코드를 리팩토링하거나 재사용할 때 플러그인 기반 로직과 CSS 스타일을 함께 유지하기 어려울 수 있습니다.
전처리기의 또 다른 문제는 CSS가 완전한 형태로 확장되면 속기로 작성된 오류가 훨씬 더 큰 혼란으로 빠르게 팽창한다는 것입니다. 플러그인을 사용할 때 많은 잠재적인 실패 지점을 추가합니다. CSS가 조금 더 강력하다면 모두 불필요할 수 있는 몇 가지 다른 작업을 수행하기 위해 여러 플러그인을 사용할 수 있습니다. 이는 개발자가 유지 관리하고 브라우저가 렌더링하고 사용자가 다운로드해야 하는 추가 부담을 만듭니다.
웹 개발의 미래에 희망이 있습니까?
2013년 Tyson Matanich는 "Media Queries Are Not the Answer: Element Query Polyfill"이라는 제목의 기사를 작성하여 많은 청중에게 요소 쿼리의 개념을 소개했습니다. CSS의 단점을 탐색하기 위해 플러그인과 폴리필을 구축하는 방법에 대한 토론이 시작되었습니다.
그 이후로 CSS 기능이 발전하기를 기다리는 동안 개발자가 몇 가지 다른 방식으로 요소 쿼리를 사용할 수 있도록 하는 여러 플러그인이 출시되었습니다.
요소 쿼리란 무엇입니까?
요소 쿼리는 규칙이 브라우저 뷰포트의 속성이 아닌 실제 요소의 속성에 적용된다는 점을 제외하면 미디어 쿼리와 유사합니다.
EQCSS의 탄생 과정
2013년 말, 저는 Ruby on Rails 웹 앱의 프론트 엔드에서 작업하고 있음을 알게 되었습니다. 앱은 사용자에게 자세한 정보를 표시해야 했으며 목표는 휴대폰, 태블릿 및 데스크톱 브라우저에서 똑같이 잘 작동하는 반응형 인터페이스를 구축하는 것이었습니다. 이것은 몇 가지 문제를 제기했으며, 그 중 하나는 표시되어야 하는 중요한 콘텐츠 중 많은 부분이 표에 가장 잘 표시된다는 점이었습니다. 예, 실제 table
요소(금융 거래, 스포츠 기록 등을 표시하기 위해)입니다.
다양한 크기의 브라우저에 대해 table
요소를 올바르게 표시하는 미디어 쿼리를 사용하여 반응형 스타일을 만들었습니다. 하지만 반응형 테이블 중 하나 가 사이드바가 포함된 템플릿에 표시되자 갑자기 모든 반응형 중단점이 반응형 중단점으로 바뀌었습니다. 그들은 단순히 200픽셀 너비의 사이드바를 고려하지 않아 항목이 겹치고 깨진 것처럼 보입니다.
또 다른 장애물: 사용자 이름의 길이는 3자에서 20자까지 다양했으며 포함된 문자 수에 따라 각 사용자 이름의 글꼴 크기를 자동으로 조정할 수 있기를 원했습니다. 사이드바에 각 사용자 이름을 입력해야 했고 20자 사용자 이름에 맞을 만큼 작지만 뷰어가 3자 사용자 이름을 볼 수 있을 만큼 큰 글꼴 크기를 선택하는 것이 까다로웠습니다.
이러한 문제를 해결하기 위해 각 레이아웃에 반응형 스타일을 적용하는 더 똑똑한 방법이 필요했기 때문에 전체 미디어 쿼리를 복사하고 코드 기반의 큰 섹션을 복제하는 경우가 많았습니다. 또 다른 임시 솔루션으로 JavaScript에 의존하여 페이지를 보고 CSS가 도달할 수 없는 위치에 스타일을 적용하는 거의 동일한 기능을 많이 작성했습니다. 잠시 후 이 모든 중복 코드의 추가 부담이 코드 기반을 짓누르기 시작했고 변경을 수행하기 어렵게 만들었습니다.
더 나은 솔루션이 있어야 한다는 것을 알았고 잠시 후 생각하기 시작했습니다. 미디어 쿼리는 필요하지 않습니다. 필요한 것은 요소 쿼리입니다!
연구 및 개발
2014년까지 저는 더 나은 스타일을 적용할 수 있도록 페이지에 나타나는 요소의 속성을 CSS에 알리는 다양한 방법을 실험하기 시작했습니다. CSS의 아름다움과 JavaScript의 힘을 결합한 스타일을 작성할 수 있는 접근 방식을 찾고 싶었습니다.
내가 포기한 몇 가지 버려진 접근 방식에는 반응형 지원을 추가하기 위해 HTML 태그에 속성을 추가하는 것과 JavaScript에서 함께 패치된 일종의 프랑켄슈타인 괴물을 생성하기 위해 JavaScript 기반 if
문 안에 CSS 코드의 전체 블록을 포함하는 방법을 찾는 것이 포함됩니다. 그리고 CSS.
그러나 일을 더 쉽게 만드는 대신 실패한 모든 접근 방식에는 한 가지 공통점이 있었습니다. 더 많은 작업을 추가했습니다! 올바른 솔루션이 수행해야 하는 작업을 단순화하고 줄일 수 있다는 것을 알고 있었기 때문에 계속 검색했습니다. 이러한 실험을 통해 요소 쿼리가 잘 작동하는 데 필요한 구문 유형에 대한 세련된 아이디어를 얻었습니다.
언급했듯이 HTML, CSS 및 JavaScript로 구축된 웹사이트의 경우 외부 지원은 프레임워크, 플러그인, 전처리기, 트랜스파일러, 편집 도구, 패키지 관리자 및 빌드 프로세스의 형태로 제공됩니다. 스택의 맨 위에 또 다른 플러그인을 추가하는 대신, 핵심 언어 중 하나인 CSS를 확장하여 웹 사이트를 구축하는 자료를 강화하고 외부 지원이 덜 필요하고 더 나은 강력한 웹 사이트를 구축할 수 있는지 궁금했습니다. 빌드 도구.
구문의 탄생
2014년 말까지 필요한 구문에 대한 더 나은 비전을 가지고 경이로운 JavaScript 코드 골퍼인 Maxime Euziere에게 연락하여 런타임 시 브라우저에서 JavaScript를 사용하여 CSS를 확장할 수 있는 가능성에 대한 그의 의견을 물었습니다. 그는 그것이 가능하다고 나에게 알렸을 뿐만 아니라 내가 그것을 할 수 있도록 도와주겠다고 제안했습니다! "요소 쿼리 CSS"의 약어인 구문을 EQCSS로 명명했습니다. 이름은 또한 "excess"라는 단어에 대한 경의입니다. 왜냐하면 모든 것이 CSS가 할 수 있는 것을 초과하기 때문입니다.
필요
구문에 대한 내 요구 사항은 가능한 한 CSS 에 가깝다는 것입니다. 구문 형광펜이 표준 CSS라고 생각하도록 속일 수 있을 정도로 가깝습니다. 그래서 저는 의미가 있는 요소 쿼리에 대한 CSS 구문을 매핑했습니다. 사람들이 놀란 구문 유형은 이미 존재하지 않습니다.
JavaScript를 사용하여 CSS에 대한 브라우저 지원을 확장하려면 플러그인을 빌드하기 위해 jQuery와 같은 라이브러리를 사용하지 않는 작업을 완료하려면 플러그인이 최대한 가볍고 간단해야 한다는 것을 알고 있었습니다. 미래에 내가 원하는 기능을 현재 지원해야 하는 브라우저에 추가할 순수한 JavaScript 라이브러리가 필요했습니다.
현재 CSS 커뮤니티에서 사용자 정의 @
규칙에 대한 논의가 집중되고 있으며 요소 쿼리에 대한 논의는 아직 예비 단계입니다. 우리는 이와 같은 기능에 대한 공식 CSS 사양이 아직 몇 년 남았을 가능성이 높으며 사양 후에도 웹사이트에서 해당 기능을 사용하기 전에 충분한 브라우저 지원을 기다려야 합니다.
이러한 기능이 CSS에 추가되기를 기다리는 것은 오늘날 웹사이트를 구축하고 수정하기 위해 이 기능이 필요할 때 의미가 없습니다.
결과
이 연구의 결과로 새로운 고급 반응 조건 세트, 범위가 지정된 스타일 및 요소를 대상으로 하는 새로운 선택기, 그리고 EQCSS.js라는 순수 JavaScript 라이브러리를 포함하는 구문이 생성되었습니다. 또한 IE(Internet Explorer) 8에 대한 지원이 선택적 외부 폴리필에서 제공되었습니다. 플러그인과 폴리필은 모두 MIT 라이선스에 따라 출시되었으며 모든 사람이 무료로 사용할 수 있습니다.
요소 쿼리의 사용 사례
플러그인 개발자
UI 구성 요소와 위젯을 만들 때 개발자는 종종 미디어 쿼리로 인해 제약을 받습니다. 플러그인을 사용하는 사람이 구성할 수 있는 다양한 레이아웃을 구축하는 것과 가장 적합한 솔루션을 구축할 수 있을 정도로 인터페이스를 단순화하는 것 사이에서 선택해야 하는 경우가 많습니다.
그러나 요소 쿼리를 사용하여 플러그인과 인터페이스를 설계할 때 예상되는 모든 상황을 포괄하는 반응형 스타일을 쉽게 작성할 수 있으므로 사용자가 내부에 어떤 콘텐츠를 넣거나 플러그인이 표시되는 위치에 관계없이 진정으로 방탄이 되도록 만들 수 있습니다. 너비가 150에서 2000픽셀 범위인 레이아웃으로 위젯의 스타일을 지정할 수 있다고 가정합니다. 그러면 해당 위젯이 웹사이트에서 어디에 표시되든 상관없이 항상 멋지게 보일 것입니다.
템플릿 빌더
웹사이트를 프로토타이핑할 때 페이지의 디자인 요소를 재구성하고 디자인을 모듈식 구성 요소의 모음으로 생각하는 것이 일반적입니다. CSS 미디어 쿼리를 작성했다면 때로 이것은 시기상조 최적화 의 경우일 수 있습니다. 요소 쿼리를 사용하여 디자인하면 응답 조건을 레이아웃에 독립적으로 유지하여 스타일을 다시 작업할 필요 없이 훨씬 더 유연하게 항목을 이동할 수 있습니다.
요소 쿼리를 사용하여 디자인하거나 조롱할 때 특히 유용하다고 생각한 사항은 다음과 같습니다.
- 탐색 모음,
- 모달,
- 가입 및 로그인 양식,
- 바닥글,
- 가격 차트,
- 방문 페이지,
- 테이블,
- 탭 상자,
- 아코디언,
- 사이드바 위젯,
- 미디어 플레이어,
- 증언 섹션.
모든 디자인 요소는 "범위"를 지정하고 페이지에서 페이지로 또는 웹사이트에서 웹사이트로 포팅할 수 있습니다.
장치 지원
모바일 장치에서 웹을 지원할 때 직면하는 문제 중 하나는 풍부한 하드웨어입니다. 기기 시장은 그 어느 때보다 세분화되어 있으며 매일 새로운 기기가 등장하고 있습니다. 더 이상 지원하는 브라우저 및 장치 목록을 유지할 수 없으므로 아직 출시되지 않은 장치에서도 디자인이 모든 곳에서 작동한다는 사실을 아는 것이 중요합니다.
요소 쿼리를 사용하면 더 나은 방식으로 웹 사이트를 디자인하고 이러한 브라우저 간 차이점을 제거할 수 있습니다.
요소 쿼리의 필요성에 대해 최근에 작성된 많은 기사에서 많은 사용 사례를 자세히 설명합니다. 그럼 사용법을 알아볼까요!
요소 쿼리를 작성하는 방법
EQCSS를 시작하는 것은 쉽습니다. EQCSS 구문을 사용하기 시작하려면 HTML의 어딘가에 JavaScript를 포함하기만 하면 됩니다.
EQCSS.js 다운로드
GitHub에서 EQCSS 프로젝트를 복제하려면 다음을 입력합니다.
git clone https://github.com/eqcss/eqcss.git
npm을 사용하는 경우 다음 명령을 사용하여 프로젝트에 EQCSS를 추가할 수 있습니다.
npm install eqcss
HTML에 EQCSS.js 추가하기
EQCSS를 다운로드한 후에는 script
태그를 사용하여 HTML에 추가할 수 있습니다.
<script src="EQCSS.js"></script>
이 파일( EQCSS.js
)에는 IE 9 이상을 포함한 모든 현재 브라우저에 대한 지원이 포함되어 있습니다. IE 8을 지원하려면 다른 많은 폴리필을 사용해야 했습니다. IE 8은 폴리필이 없는 CSS 미디어 쿼리도 지원하지 않는다는 점을 염두에 두십시오. 따라서 여기에서도 작동하는 요소 쿼리를 얻을 수 있다는 것이 매우 놀랍습니다. EQCSS를 사용하는 웹 사이트에 대한 IE 8 지원을 포함하려면 기본 플러그인에 대한 링크 앞에 다음 링크를 추가하십시오.
<!‐‐[if lt IE 9]><script src="EQCSS‐polyfills.js"></script><![endif]‐‐>
EQCSS 실행
기본적으로 EQCSS 플러그인은 페이지가 로드되면 발견한 모든 스타일을 계산하고 미디어 쿼리와 유사하게 브라우저 크기가 조정되는 것을 감지할 때마다 계산합니다. 또한 JavaScript로 EQCSS.apply()
를 수동으로 호출하여 언제든지 스타일을 다시 계산할 수 있습니다. 이는 페이지에서 콘텐츠가 업데이트되면 유용할 수 있습니다.
요소 쿼리 CSS 작성
EQCSS.js 플러그인은 몇 가지 다른 방법으로 스타일을 읽을 수 있습니다. HTML 페이지의 모든 style
태그에 EQCSS를 포함할 수 있습니다. 외부 CSS 스타일 시트에서 EQCSS를 작성할 수도 있습니다.
EQCSS 기반 코드를 CSS와 별도로 유지하려면 유형이 text/eqcss
로 설정된 script
태그를 사용하여 EQCSS 구문을 로드할 수 있습니다. 이와 같이 태그에 스타일을 인라인으로 추가하거나 <script type=“text/eqcss” src=styles.eqcss></script>
를 사용하여 외부 .eqcss
스타일 시트에 연결할 수 있습니다. 그러면 styles.eqcss
라는 파일이 로드됩니다. .
요소 쿼리의 구조
스타일 범위
요소 쿼리를 작성하기 위한 EQCSS의 구문은 CSS 미디어 쿼리의 형식화와 매우 유사하지만 @media
대신 @element
로 쿼리를 시작합니다. 우리가 제공해야 하는 유일한 다른 정보는 이러한 스타일을 적용해야 하는 하나 이상의 선택기입니다. 다음은 <div class=“widget”>
이라는 요소에 대한 새 범위를 만드는 방법입니다.
@element '.widget' { }
따옴표 사이의 요소(이 경우 .widget
)는 유효한 CSS 선택기일 수 있습니다. 이 쿼리를 사용하여 .widget
요소에 대한 새 범위를 만들었습니다. 범위에 대한 응답 조건을 아직 포함하지 않았으므로 이와 같은 쿼리의 스타일은 항상 범위가 지정된 요소에 적용됩니다.
한 번에 전체 페이지가 아닌 하나 이상의 요소로 스타일 범위를 지정하는 기능이 없으면 해당 요소에만 반응형 쿼리를 적용할 수 없습니다. 요소 수준 범위를 생성하고 나면, 예를 들어 $parent
메타 선택기와 같은 parentNode
구문의 고급 기능을 사용하는 것이 쉬워집니다. 요소. 이것은 거대하다!
사실, CSS에는 지정된 요소의 직계 자식인 요소를 선택할 수 있는 >
와 함께 이미 직접 후손 선택기가 포함되어 있습니다. 그러나 CSS는 현재 가계도의 다른 방향으로 이동하여 부모 요소라고 하는 다른 요소를 포함하는 요소를 선택할 수 있는 방법을 제공하지 않습니다. "CSS 선택기 레벨 4" 사양에는 이제 jQuery의 :has()
선택기와 유사한 방식으로 작동하는 :has()
has() 선택기가 포함되지만 현재 브라우저 지원은 nil입니다. 범위가 지정된 CSS는 다른 종류의 부모 선택기를 가능하게 합니다.
이제 .widget
요소의 컨텍스트에서 범위를 열었으므로 해당 관점에서 자체 부모 요소를 대상으로 하는 스타일을 작성할 수 있습니다.
@element '.widget' { $parent { /* These styles apply to the parent of .widget */ } }
모든 요소 쿼리에서 사용할 수 있는 특수 선택기의 또 다른 예는 이전 및 다음 형제 요소를 나타내는 $prev
및 $next
선택기입니다. CSS가 .widget + *
와 같은 선택기를 사용하여 위젯의 다음 형제에 도달할 수 있지만 CSS에서 뒤로 도달하여 다른 요소 바로 앞에 오는 요소를 선택할 수 있는 방법은 없습니다.
<section> <div>This will be the previous item</div> <div class="widget">This is the scoped element</div> <div>This will be the next item</div> </section> <style> @element '.widget' { $prev { /* These styles apply to the element before .widget */ } $next { /* These styles apply to the element after .widget */ } } </style>
요소 쿼리
개발자는 브라우저 뷰포트의 높이 또는 너비를 기반으로 스타일을 적용하여 반응형 디자인을 위해 CSS 미디어 쿼리를 가장 자주 사용합니다. EQCSS 구문은 많은 새로운 유형의 응답 조건을 지원합니다. 브라우저의 너비와 높이만으로 작업하는 대신, 얼마나 많은 자식 요소가 포함되어 있는지, 현재 요소에 얼마나 많은 문자나 텍스트 행이 있는지와 같은 고유한 속성을 기반으로 요소에 적용되는 스타일을 작성할 수 있습니다. .
범위가 지정된 스타일에 이러한 응답 조건을 추가하는 것은 미디어 쿼리의 형식을 지정하는 방법과 유사합니다. 확인하려는 각 조건에 대해 and (condition: value)
을 추가합니다. 이 예에서는 .widget
요소가 페이지에 최소 500픽셀 너비를 표시하는지 확인합니다.
@element '.widget' and (min‐width: 500px) { /* CSS rules here */ }
요소 쿼리의 구문은 다음과 같이 분류됩니다.
- 요소 쿼리
@element selector_list [ condition_list ] { css_code }
- 선택기 목록
" css selector [ "," css selector ]* "
- 조건 목록
and ( query_condition : value ) [ "and (" query condition ":" value ")" ]*
- 값
number [ css unit ]
- 쿼리 조건
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
- CSS 단위
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
다른 예로, .widget
요소가 500픽셀 너비에 도달할 때 body
요소를 빨간색으로 바꾸는 쿼리를 작성하는 방법은 다음과 같습니다.
@element '.widget' and (min‐width: 500px) { body { background: red; } }
.widget
요소 자체가 아니라 .widget
이 특정 너비에 도달하면 body
요소가 변경됩니다.
요소 쿼리 조건
다음은 EQCSS가 지원하는 반응 조건의 전체 목록입니다.
너비 기반 조건
- 픽셀에 대한
min-width
데모, 백분율에 대한 데모 - 픽셀에 대한
max-width
데모, 백분율에 대한 데모
높이 기반 조건
- 픽셀에 대한
min-height
데모, 백분율에 대한 데모 - 픽셀에 대한
max-height
데모, 백분율에 대한 데모
개수 기반 조건
- 블록 요소용
min-characters
데모, 양식 입력용 데모 - 블록 요소에 대한
max-characters
데모, 양식 입력에 대한 데모 -
min-lines
데모 -
max-lines
데모 -
min-children
데모 -
max-children
데모
스크롤 기반 조건
-
min-scroll-y
데모 -
max-scroll-y
데모 -
min-scroll-x
데모 -
max-scroll-x
데모
진정한 다차원 반응 스타일을 위해 요소 쿼리에서 이러한 조건을 얼마든지 결합할 수 있습니다. 이렇게 하면 요소가 렌더링되는 방식을 훨씬 더 유연하게 제어할 수 있습니다. 예를 들어, 표시할 수 있는 공간이 600픽셀 미만일 때 15자를 초과하는 헤더의 글꼴 크기를 줄이려면 max‐characters: 15
및 max‐width: 600px
조건을 결합할 수 있습니다.
h1 { font‐size: 24pt; } @element 'h1' and (min‐characters: 16) and (max‐width: 600px) { h1 { font‐size: 20pt; } }
메타 선택기
반응형 조건으로 범위가 지정된 스타일을 작성하기 시작하면 발생할 수 있는 문제 중 하나는 동일한 선택기의 여러 인스턴스가 페이지에 있는 경우 요소 쿼리에서 해당 선택기를 사용하면 해당 선택기의 모든 인스턴스에 스타일이 적용된다는 것입니다. 조건과 일치하는 페이지가 있을 때 이전의 .widget
예제를 사용하여 페이지에 두 개의 위젯이 있고(하나는 사이드바에, 다른 하나는 전체 너비로 표시) 다음과 같이 요소 쿼리를 작성했다고 가정합니다.
@element '.widget' and (min‐width: 500px) { .widget h2 { font‐size: 14pt; } }
즉, 페이지의 .widget
요소 중 하나 의 너비가 500픽셀 이상인 경우 스타일이 두 .widget
요소에 모두 적용됩니다. 이것은 아마도 대부분의 경우 우리가 원하는 일이 아닐 것입니다. 이것은 메타 선택자가 들어오는 곳입니다!
요소 쿼리를 구성하는 두 부분은 선택기와 응답 조건입니다. 따라서 선택기 와 반응 조건 모두와 동시에 일치하는 페이지의 요소만 대상으로 지정하려는 경우 메타 선택기 $this
를 사용할 수 있습니다. 스타일이 min‐width: 500px
조건과 일치하는 .widget
요소에만 적용되도록 마지막 예제를 다시 작성할 수 있습니다.
@element '.widget' and (min‐width: 500px) { $this h2 { font‐size: 14pt; } }
일반 CSS에는 없는 EQCSS 구문에서 많은 새로운 선택기가 지원됩니다. 전체 목록은 다음과 같습니다.
-
$this
데모 -
$parent
데모 -
$root
데모 -
$prev
데모 -
$next
데모
이러한 선택기는 요소 쿼리에서만 작동합니다.
JavaScript와 CSS 사이의 포털 열기
-
eval(')
데모
EQCSS의 마지막이자 마지막 기능은 eval(')
입니다. 이 출입구를 통해 CSS에서 액세스할 수 있는 JavaScript의 모든 힘이 있습니다. JavaScript는 요소에 스타일을 적용할 수 있지만 현재 :before
및 :after
의사 요소와 같은 일부 항목에 도달하는 데 어려움이 있습니다. 하지만 CSS가 다른 방향에서 JavaScript에 도달할 수 있다면 어떨까요? JavaScript가 CSS 속성을 설정하는 대신 CSS가 JavaScript를 인식할 수 있다면 어떨까요?
여기에서 eval(')
이 사용됩니다. CSS에서 JavaScript 변수 값을 사용할지 여부에 관계없이 모든 JavaScript에 액세스하고 평가하여 eval('new Date().getFullYear()')
), JavaScript가 측정할 수 있는 브라우저 및 기타 요소(예: eval('innerHeight')
)에 대한 값을 확인하거나 JavaScript 함수를 실행하고 CSS 스타일에서 반환하는 값을 사용합니다. 다음은 <footer>
요소에서 2016
을 출력하는 예입니다.
@element 'footer' { $this:after { content: " eval('new Date().getFullYear()')"; } }
eval(') 내부에서 $it 사용
JavaScript를 평가하는 동안 eval(')
은 $this
에 대한 스타일이 적용되는 동일한 요소인 활성 범위 요소의 컨텍스트에서도 작동합니다. 코드를 구조화하는 데 도움이 되는 경우 eval(')
로 작성된 JavaScript에서 $it
을 범위 요소의 자리 표시자로 사용할 수 있지만 생략하면 동일한 방식으로 작동합니다. 예를 들어 "hello"라는 단어가 포함된 div
가 있다고 가정해 보겠습니다. 다음 코드는 "hello hello"를 출력합니다.
<div>hello</div> <style> @element 'div' { div:before { content: "eval('$it.textContent') "; } } </style>
여기에서 $it
은 현재 범위가 지정된 선택기이기 때문에 div
를 참조합니다. $it
를 생략하고 다음 코드를 작성하여 동일한 것을 표시할 수도 있습니다.
@element 'div' { div:before { content: "eval('textContent') "; } }
eval(')
은 페이지가 로드된 후 페이지에서 발생하는 측정 또는 이벤트를 CSS가 인식하지 못하는 상황에서 유용할 수 있습니다. 예를 들어 YouTube 동영상을 포함하는 데 사용되는 iframe 요소에는 너비와 높이가 지정되어 있습니다. CSS에서 너비를 auto
으로 설정할 수 있지만 비디오가 사용 가능한 공간을 채우도록 확장될 때 너비와 높이의 정확한 종횡비를 유지하는 쉬운 방법은 없습니다.
크기를 조정하는 동안 반응형 종횡비를 유지하기 위한 일반적인 해결 방법은 종횡비를 유지해야 하는 콘텐츠를 래퍼에 배치한 다음 유지하려는 너비와 높이의 비율을 기반으로 하는 값으로 래퍼에 패딩을 추가하는 것입니다. 이것은 작동하지만 모든 비디오의 종횡비를 미리 알아야 할 뿐만 아니라 반응형으로 포함하려는 각 비디오에 대해 더 많은 HTML 마크업(래퍼 요소)이 필요합니다. 반응형 비디오가 있는 모든 웹 사이트에 이를 곱하면 CSS가 조금만 더 똑똑했다면 거기에 있을 필요가 없었을 많은 쓰레기입니다.
반응형 종횡비에 대한 더 나은 접근 방식은 패딩 없이 래퍼에 각 비디오를 배치한 다음 찾은 각 비디오의 종횡비를 계산하고 각 래퍼에 정확한 패딩 양을 적용하는 JavaScript 라이브러리를 작성하는 것입니다.
하지만 CSS 가 이러한 측정에 직접 액세스할 수 있다면 어떨까요? 모든 다른 종횡비에 대한 CSS를 하나의 규칙으로 통합할 수 있을 뿐만 아니라 페이지가 로드된 후 이를 평가할 수 있다면 미래에 제공할 모든 비디오의 크기를 반응적으로 조정하는 하나의 규칙을 작성할 수 있습니다. 그리고 우리는 래퍼 없이 이 모든 것을 할 수 있습니다!
이것이 사실이라고 보기에는 너무 좋은 것 같으면 이것을 확인하십시오. 다음은 EQCSS에서 래퍼 없이 반응형으로 크기를 조정하는 iframe 요소를 작성하는 방법입니다.
@element 'iframe' { $this { margin: 0 auto; width: 100%; height: eval('clientWidth/(width/height)'); } }
여기서 width
와 height
HTML의 iframe에 있는 width=“”
및 height=“”
속성을 나타냅니다. JavaScript는 가로 세로 비율을 제공하는 (width/height)
계산을 수행할 수 있습니다. 임의의 너비에 적용하려면 iframe 요소의 현재 너비를 비율로 나누면 됩니다.
이것은 CSS의 간결함과 가독성, 그리고 JavaScript의 모든 기능을 가지고 있습니다. 추가 래퍼, 추가 클래스 및 추가 CSS가 필요하지 않습니다.
그러나 eval(')
에 주의하십시오. CSS 표현이 과거에 위험하다고 여겨졌던 데는 이유가 있고, 우리가 그 아이디어를 시도한 데도 이유가 있습니다. 페이지에 요소를 적용하는 요소의 수나 스타일을 다시 계산하는 빈도에 주의하지 않으면 JavaScript가 필요 이상으로 수백 배 더 많은 작업을 실행하게 될 수 있습니다. 고맙게도 EQCSS를 사용하면 EQCSS.apply()
또는 EQCSS.throttle()
을 호출하여 스타일을 수동으로 다시 계산할 수 있으므로 스타일이 업데이트되는 시기를 더 잘 제어할 수 있습니다.
위험 지역!
조건이나 스타일이 충돌하는 쿼리를 생성하면 다른 문제가 발생할 수 있습니다. CSS와 마찬가지로 EQCSS는 특정 계층을 사용하여 위에서 아래로 읽습니다. CSS는 선언적 언어이지만 몇 가지 고급 기능이 포함되어 있습니다. 프로그래밍 언어로서 Turing-complete가 되는 것은 불과 몇 걸음 거리에 있습니다. 지금까지 CSS 디버깅은 매우 간단한 작업이었지만 EQCSS는 CSS를 단순히 해석된 선언적 언어에서 CSS와 브라우저 사이에 추가 해석 레이어가 있는 동적 스타일 시트 언어 로 전환합니다. 이 새로운 영역에는 다양한 잠재적인 새로운 함정이 있습니다.
다음은 EQCSS의 상호 루프의 예입니다. 일반적인 CSS 미디어 쿼리는 설계상 영향을 받지 않습니다.
@element '.widget' and (min‐width: 300px) { $this { width: 200px; } }
나는 이것을 jekyll: hide;
CSS. 그러나 한 스타일이 계속해서 자체적으로 트리거되는 것 외에도 서로를 트리거하는 여러 쿼리를 작성할 가능성이 있습니다. 이를 "이중 역 상호 루프"라고 하는 것 중에서 가장 불쾌합니다.
@element '.widget' and (min‐width: 400px) { $this { width: 200px; } } @element '.widget' and (max‐width: 300px) { $this { width: 500px; } }
이론적으로 그 불행한 위젯은 루프에 갇혀 시간이 끝날 때까지 200~500픽셀 사이의 크기를 조정하고 너비를 결정할 수 없습니다. 이와 같은 경우 EQCSS는 평가된 순서대로 규칙을 계산하고 승자를 수여하고 계속 진행합니다. 이러한 규칙이 나타나는 순서를 다시 정렬하면 동일한 특이성이 있는 경우 후자의 스타일이 항상 이깁니다.
어떤 사람들은 루프(또는 이중 역 역 루프)를 생성하는 기능이 설계상의 결함이라고 말하지만 루프가 가능하지 않도록 하려면 대부분의 구문이 제공하는 값입니다. 반면에 JavaScript에서 무한 루프를 만드는 것은 매우 쉽지만 이는 언어의 결함으로 간주되지 않습니다. 이는 JavaScript의 힘의 증거로 간주됩니다! 요소 쿼리와 동일합니다.
요소 쿼리 디버깅
현재, 디버깅 요소 쿼리는 웹 검사기와 같은 도구가 페이지에서 계산된 스타일을 보여주기 전에 미디어 쿼리를 디버깅하는 것과 약간 비슷할 수 있습니다. 현재로서는 요소 쿼리를 디버깅하고 개발하려면 개발자가 어떤 반응 동작이 일어나야 하는지에 대한 멘탈 모델을 유지해야 합니다. 미래에는 EQCSS를 인식하는 개발자 도구를 빌드하는 것이 가능할 수 있지만 현재 모든 주요 브라우저의 개발자 도구는 EQCSS가 페이지의 요소에 이미 적용한 스타일만 인식하고 있으며 인식하지 못합니다. EQCSS가 보고 있는 반응 조건.
요소 쿼리로 디자인하는 방법
요소 쿼리를 사용하는 가장 간단한 방법은 미디어 쿼리를 사용하는 기존 디자인을 요소 쿼리로 변환하여 요소와 반응 스타일을 하나의 레이아웃에서 "해방"하고 다른 페이지 및 프로젝트에서 해당 코드를 쉽게 재사용할 수 있도록 하는 것입니다. 다음 미디어 쿼리와 요소 쿼리는 같은 의미일 수 있습니다.
footer a { display: inline-block; } @media (max‐width: 500px) { footer a { display: block; } }
footer a { display: inline-block; } @element 'footer' and (max‐width: 500px) { $this a { display: block; } }
차이점은 원본 예에서 바닥글 링크는 브라우저 의 너비가 최소 500픽셀이 될 때까지 display: block
으로 유지된다는 것입니다. 요소 쿼리를 사용하는 두 번째 예는 footer
요소가 전체 너비인 경우에만 동일하게 보입니다.
원래 미디어 쿼리에서 이 스타일을 해제한 후, 이제 바닥글을 모든 너비의 컨테이너에 배치할 수 있으며 바닥글에 반응형 스타일을 적용해야 할 때(즉, 500픽셀보다 좁은 경우) 적용된.
-
EQCSS.js
가 대상 문서의 HTML에 있는지 확인하십시오. - CSS에서
@media
를@element
로 바꿉니다. - 각
@element
쿼리의 범위에 CSS 선택기를 추가합니다. - 선택 사항: 범위가 지정된 요소의 발생을 요소 쿼리에서
$this
로 바꿉니다.
변환하려는 디자인 구성 요소가 원래 브라우저 뷰포트의 전체 너비를 사용하여 표시하도록 설계된 경우가 아니면 요소 쿼리로 변환한 후 중단점을 조정해야 할 수 있습니다.
종속 방지
EQCSS 스타일을 작성하는 경험은 일반 CSS를 작성하는 경험과 유사합니다. 새로운 방식으로 함께 작동하는 데 도움이 되는 몇 가지 추가 기능만 있으면 좋아하는 CSS 속성과 기술이 모두 그대로 있습니다. EQCSS는 표준 CSS를 브라우저에 출력하기 때문에 브라우저가 기본적으로 지원하는 CSS 기능은 EQCSS와 함께 사용할 때 작동합니다. 요소 쿼리 및 범위 지정 스타일과 같은 기능이 CSS에 지정되고 브라우저에서 지원된다면, EQCSS 코드에서 즉시 사용을 시작할 수 있을 뿐만 아니라 브라우저가 지원하지 않는 다른 기능에 대해서는 여전히 EQCSS에 의존할 수 있습니다. 아직 기본적으로 지원합니다.
text/eqcss
유형을 사용하여 CSS와 자체 스크립트에서 모두 EQCSS 구문을 직접 사용할 수 있기 때문에 CSS가 기본 요소 쿼리에 대한 구문을 개발하는 경우에도 EQCSS를 스크립트로 로드하고 충돌을 피할 수 있습니다. .
앞으로 브라우저 개발자가 현재 실험 중인 솔루션 중 하나는 플러그인 개발자가 브라우저 자체에 지원을 추가하는 것과 같은 새로운 방식으로 CSS를 확장할 수 있는 액세스를 제공하는 Houdini입니다. 언젠가는 EQCSS 구문을 해석하고 이러한 기능을 현재 JavaScript 라이브러리에서 허용하는 것보다 더 직접적이고 성능이 뛰어난 방식으로 브라우저에 제공하는 더 효율적인 플러그인을 작성하는 것이 가능할 수 있습니다.
그렇다면 여전히 미디어 쿼리를 사용해야 합니까?
예, 요소 쿼리가 스타일로 요소를 대상으로 하는 새롭고 흥미로운 방법을 많이 제공하지만 미디어 쿼리(제한적이지만)는 JavaScript에 의존하여 계산하는 스타일보다 브라우저에서 항상 더 빠르게 실행됩니다. 그러나 CSS 미디어 쿼리는 화면의 HTML 스타일을 지정하는 것 이상을 위한 것입니다. CSS 미디어 쿼리는 인쇄 기반 쿼리 및 웹사이트에서 정보를 표시하는 기타 방법도 지원합니다. EQCSS는 인쇄 스타일과 같은 미디어 쿼리와 함께 사용할 수 있으므로 이제 요소 쿼리도 사용할 수 있기 때문에 미디어 쿼리를 폐기할 필요가 없습니다!
20 ⁄ 20 비전으로 설계
CSS의 미래를 위해 우리가 할 수 있는 최선은 오늘 가능한 한 이러한 아이디어를 실험하는 것입니다. 이러한 기능에 대한 많은 브레인스토밍과 이론화는 실제로 기능을 구현하고 사용하여 유용하고 강력하게 만드는 기술을 발견하는 것만큼 유용하지 않을 것입니다.
요소 쿼리에 대한 솔루션을 제공하는 것 외에도 EQCSS.js는 CSS를 확장하는 다른 실험을 위한 플랫폼 역할도 하기를 바랍니다. 새로운 반응형 조건, 새로운 CSS 속성 또는 코드에서 사용할 새로운 선택기에 대한 아이디어가 있는 경우 EQCSS.js를 분기하고 아이디어를 포함하도록 수정하면 적은 노력으로 대부분의 방법을 얻을 수 있습니다.
모듈식 설계
In designing layouts using element queries, the biggest shift is learning how to stop viewing the DOM from the top down and from the perspective of only the root HTML element, and to start thinking about individual elements on the page from their own perspectives within the document.
The old paradigms of “desktop-first” and “mobile-first” responsive design aren't relevant any longer — the new way of building layouts approaches design “element-first.” Using element queries enables you to work on the individual parts that make up a layout, in isolation from one another, styling them to a greater level of detail. If you are using a modular approach for your back-end code already but have so far been unable to package your CSS with your modules because of the difficulties of styling with media queries alone, then element queries will finally allow you to modularize your styles in the same way.
Thinking Element-First
Element-first design is in the same spirit as the atomic design principle but looks different in practice from how most people have implemented atomic design in the past.
For example, let's say you have some HTML like the following, and the desired responsive behavior can be explained as, “The search input and button are displayed side by side until the form gets too narrow. Then, both the input and the button should be stacked on top of each other and displayed full width.”
<form> <input type=search> <input type=button value=Search> </form>
Desktop-First Approach
In a desktop-first mindset, you would write styles for the desktop layout first and then add responsive support for smaller screens.
input { width: 50%; float: left; } @media (max‐width: 600px) { input { width: 100%; float: none; } }
Mobile-First Approach
In a mobile-first mindset, you would design the mobile view first and add support for the side-by-side view only when the screen is wide enough.
input { width: 100%; } @media (min‐width: 600px) { input { width: 50%; float: left; } }
Element-First Approach
In the first two examples, the media breakpoint was set to 600 pixels, and not because that's how wide the inputs will be when they switch. Chances are, the search input is probably inside at least one parent element that would have margins or padding. So, when the browser is 600 pixels wide, those inputs might be somewhere around 550 or 525 pixels wide on the page. In a desktop-first or mobile-first approach, you're always setting breakpoints based on the layout and how elements show up within it. With an element-first layout, you're saying, “I don't care how wide the browser is. I know that the sweet spot for where I want the inputs to stack is somewhere around 530 pixels wide.” Instead of using a media query to swap that CSS based on the browser's dimensions, with element-first design, we would scope our responsive style to the form
element itself, writing a style like this:
input { width: 100% } @element 'form' and (min‐width: 530px) { $this input { width: 50%; float: left; } }
The code is similar to that of the two previous methods, but now we are free to display this search input anywhere — in a sidebar or full width. We can use it in any layout on any website, and no matter how wide the browser is, when the form itself doesn't have enough room to display the inputs side by side, it will adapt to look its best.
시작하기 위한 리소스
EQCSS-Enabled Template
<!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title></title> <style></style> </head> <body> <!‐‐[if lt IE 9]><script src="https://elementqueries.com/EQCSS‐polyfills.min.js"></script><![endif]‐‐> <script src="https://elementqueries.com/EQCSS.min.js"></script> </body> </html>
시민
- Responsive Aspect Ratio
- Sticky Scroll Header
- Blockquote Style
- 달력
- Content Demo
- Counting Children Demo
- Date Demo
- Zastrow-style Element Query Demo Demo
- Flyout Demo
- Headline Demo
- Media Player Demo
- Message Style Demo
- Modal Demo
- Nav Demo
- Parent Selector Demo
- Pricing Chart Demo
- Responsive Tables Demo
- Scroll-triggered Blocker Demo
- Signup Form Demo
- Testimonials Block Demo
- Tweet-Counter Demo
- JS Variables Demo
- Responsive Scaling Demo
- Geometric Design Demo
- Responsive Order Form
- Element Query Grid
- JS Functions in CSS
- Responsive Content Waterfall
추가 읽기
You can find the EQCSS project on GitHub, demos, documentation and articles on the EQCSS website. An ever-growing number of Codepens use EQCSS, and you can create your own pen by forking the batteries-included template that comes hooked up with EQCSS. You can also play with the EQCSS tool that I built to preview if your EQCSS code is working as expected.
즐거운 해킹!