一.LVHA
실제로는 LVFHA 여야 합니다. 즉:
a:link {/* 방문하지 않은 하이퍼링크의 스타일 */}
a:visited {/* 방문한 하이퍼링크의 스타일 */}
a:focus {/* 포커스를 가진 하이퍼링크의 스타일 */}
a:hover {/* 마우스 호버 시의 하이퍼링크의 스타일 */}
a:active {/* 사용자 입력으로 활성화된 하이퍼링크의 스타일 */}
이 5 개는 모두 의사 클래스로, 5 가지 상태를 나타냅니다. 그 중 link 와 visited 는 하이퍼링크 전용으로, 링크 의사 클래스로 분류할 수 있습니다. 반면 focus, hover, active 는 하이퍼링크뿐만 아니라 다른 요소에도 적용 가능하며 동적 ���사 클래스라고 합니다
LVFHA 원칙은 하이퍼링크 (href 속성이 있는 a 태그) 에 위의 5 개 의사 클래스를 적용할 때 이 고정된 순서를 준수해야 한다는 것입니다
二.의사 클래스와 의사 요소
의사 클래스는 클래스처럼 DOM 트리에 이미 존재하는 특정 요소를 선택하는 데 사용됩니다. 선택 조건에는 두 가지가 있습니다:
-
상태: 요소가 특정 상태에 있는지 여부. 예를 들어, 사용자가 방문함 (
link/visited), 현재 포커스를 가짐 (focus), 특정 언어 환경에 있음 (lang) -
구조: 요소가 DOM 구조와 관련된 특정 요구 사항을 충족하는지 여부. 예를 들어, 장남인 요소 (
first-child), CSS3 에서 추가된 루트 요소인 요소 (root) 와 많은 구조적 의사 클래스 (nth-*,*-of-type등)
의사 요소는 요소에 더 가깝고, DOM 트리에 존재하지 않는 요소 (또는 요소의 일부) 를 선택하는 데 사용됩니다. 의사 클래스의 번영한 대가족에 비해 의사 요소는 다소 외로워 보입니다. 현재 (2017/11/4) 까지 CSS3 명세에는 여전히 4 개의 의사 요소만 있습니다 (CSS2.1 도 4 개였습니다):
-
첫 글자: 요소에 포함된 텍스트 콘텐츠의 첫 글자를 선택합니다 (텍스트 콘텐츠에는 자식 요소에서 온 것이 포함되며, 즉 태그 계층을 넘어 텍스트를 선택할 수 있습니다)
-
첫 줄: 요소에 포함된 텍스트 콘텐츠의 첫 줄을 선택합니다 (위와 동일)
-
before: 콘텐츠 생성에 사용되며, 지정된 요소의 콘텐츠 시작 위치에 요소를 생성합니다 (생성된 콘텐츠는 요소의 콘텐츠 영역 내에 위치합니다)
-
after: 콘텐츠 생성에 사용되며, 지정된 요소의 콘텐츠 끝 위치에 요소를 생성합니다 (위와 동일)
의사 클래스와 의사 요소의 최대 차이점 은 선택 대상 콘텐츠가 DOM 상에 존재하는지 여부입니다. 존재하면 의사 클래스, 존재하지 않으면 의사 요소에 속합니다. 다른 관점에서 보면, 문서의 일부 콘텐츠에 스타일을 지정하려면 먼저 (선택자를 사용하여) 해당 부분의 콘텐츠를 선택해야 합니다. 이때 두 가지 상황에 직면합니다:
-
대상 콘텐츠가 우연히 어떤 태그로 감싸져 있는 경우, 이 태그 전체에 스타일을 설정하면 목적을 달성할 수 있습니다
-
대상 콘텐츠 전후에 범위를 정하는 태그가 없어 직접 스타일을 설정할 수 없는 경우, 대상 콘텐츠를 감싸기 위해 임시 태그를 삽입하고 이 임시 태그에 스타일을 설정해야 합니다
첫 번째 상황은 의사 클래스로 처리하며, 의사 클래스 선택자를 사용하여 특정 상태 또는 특정 구조적 특징을 가진 기존 요소를 찾아내고 스타일을 적용합니다. 두 번째 상황은 추가 태그를 수동으로 삽입하여 첫 번째 상황으로 변환하거나 (일부 시나리오에서는 태그를 추가해도 달성할 수 없는 경우가 있습니다. 예를 들어, 첫 줄 또는 태그 계층을 넘는 시나리오), 의사 요소로 해결합니다. 이는 브라우저에 가상 태그를 삽입하여 대상 콘텐츠를 감싸고 스타일을 적용하도록 요청하는 것과 동일합니다
P.S. CSS3 선택자에 대한 자세한 정보는 CSS 선택자 분류 요약 을 참조하십시오
三.a 태그의 6 가지 상태
LVFHA 의사 클래스는 하이퍼링크에 5 가지 상태를 제공하며, 6 번째는 앵커가 아닌 하이퍼링크를 가리킵니다
link 의사 클래스가 존재하는 의미 중 하나는 하이퍼링크와 앵커를 구분하는 것입니다. link 의사 클래스는 href 가 있는 a 태그 (즉, 하이퍼링크) 만 매칭하며, 앵커는 매칭하지 않습니다
일반적인 데스크톱 브라우저 환경에서 a 태그의 6 가지 상태와 해당 트리거 동작은 각각 다음과 같습니다:
a {/*任意의 상태의 a 태그, 하이퍼링크인지 앵커인지 묻지 않음 */}
a:link {/* 방문하지 않은 하이퍼링크 */}
a:visited {/* 방문한 하이퍼링크, 하이퍼링크를 클릭하고 현재 페이지로 돌아오면 이 하이퍼링크는 visited 상태가 됩니다 */}
a:focus {/* 포커스를 얻은 하이퍼링크, tab 키로 하이퍼링크를 선택하거나 하이퍼링크를 길게 누르고 마우스를 이동 */}
a:hover {/* 마우스 호버 시의 하이퍼링크, 마우스가 하이퍼링크를 지나거나 하이퍼링크 위에 호버하면 이 하이퍼링크는 hover 상태가 됩니다 */}
a:active {/* 활성화 상태의 하이퍼링크, 마우스가 하이퍼링크 위에서 눌렸을 때 */}
그 중 focus, hover, active 는 구분하기 어렵고, focus 는 지속적인 상태이며, hover, active 는 짧은 상태입니다. 더욱 hover, active 를 세분화하면 후자는 전자의 특수한 상태입니다 (터치 디바이스 제외). 예를 들어:
a:focus {border: 1px solid green;}
a:hover {border-color: red;}
a:active {border-style: dashed;}
그렇다면 다음 연속 작업에 해당하는 상태와 스타일은 각각:
tab 키 누름 -> focus -> 녹색 실선 테두리
다른 빈 공간 클릭 -> a & link | visited -> 해당 스타일
마우스가 지날 때 -> hover -> 테두리 없음
마우스가 호버할 때 -> hover -> 테두리 없음
마우스 누름 -> focus & hover & active -> 빨간색 점선 테두리
마우스를 하이퍼링크 밖으로 이동하고 떼기 -> focus -> 녹색 실선 테두리
(다른 곳을 클릭하지 않으면 하이퍼링크는 항상 focus 상태입니다)
마우스가 지날 때 -> focus & hover -> 빨간색 실선 테두리
focus 가 지속적인 상태이므로 짧은 hover, active 앞에 배치해야 합니다. 그렇지 않으면 마지막에 마우스가 지날 때 hover 스타일이 표시되지 않습니다 (캐스케이딩 규칙에 따라 먼저 선언된 hover 가 focus 에 덮어씌워지기 때문입니다)
focus, hover, active 3 개 상태에는 중복이 있으므로 특정 선언 순서를 유지하여 캐스케이딩 결과가 스타일시트 작성자의 예상과 일치하도록 권장합니다. 반면 link 와 visited 는 상호 배타적이며 중복이 없으므로 둘의 상대적 순서는 중요하지 않습니다 (VLFAH 도 합리적이며, "애증" 순서는 기억하기 쉬울 뿐입니다). 마찬가지로, link/visited 는 영구적인 상태이므로 짧은 상태와 영구적인 상태에 표현 기회를 주기 위해 focus/hover/active 를 뒤에 배치하고, 긴 상태의 캐스케이딩 우선순위를 낮추어 LVFHA 원칙이 생겼습니다
또한, 명세서는 focus, hover, active 에 해당하는 상태의 시작 및 종료 조건을 명확히 설명하지 않았습니다:
CSS 는 어떤 요소가 위의 상태가 될 수 있는지, 그리고 이러한 상태에 어떻게 들어가고 나가는지 정의하지 않았습니다. 스크립트는 요소가 사용자 이벤트에 응답하는지 여부를 변경할 수 있으며, 다른 디바이스와 UA 는 요소를 가리키고 활성화하는 방식이 다릅니다
CSS 2.1 은 ':active' 또는 ':hover' 요소의 부모도 이 상태에 있는지 정의하지 않았습니다
(5.11.3 동적 의사 클래스::hover, :active 와 :focus 에서 발췌)
따라서 동적 의사 클래스의 트리거 동작을 확정할 수 없으며, 이 몇 가지 의사 클래스가 어떤 요소에 적용되는지도 확정할 수 없습니다 (폼 요소, div 등은 지원할 수도 있고 지원하지 않을 수도 있음). ���두 사용자 에이전트의 구현에 달려 있습니다
四.조합 의사 클래스
LVFHA 순서를 따르는 것을 권장하는 것은 캐스케이딩 규칙을 고려한 것으로, 그렇지 않으면 덮어씌워져 동명 규칙이 무효화될 수 있습니다. 예를 들어:
a:hover {text-decoration: underline overline;}
a:link {text-decoration: none;}
a:visited {text-decoration: none;}
hover 스타일 (小技巧: 마우스가 지날 때 상划线와 하划线를 동시에 표시) 은 영원히 유효하지 않습니다. text-decoration 속성이 항상 아래 두 줄 중 하나에 덮어씌워지기 때문입니다
물론, 전제 조건은 스타일 규칙에 충돌이 존재하는 경우 (동명 속성이고 소스, 중요성, 특수성이 모두 동일함) 에 선언 순서로 충돌을 해결합니다. 이때 LVFHA 순서가 실제로 작동합니다. 다시 말해, 스타일 충돌이 존재하지 않으면 선언 순서는 중요하지 않습니다
즉, 다른 방법으로 스타일 충돌 발생을 피하면 LVFHA 순서를 준수할 필요가 없습니다. 예를 들어, 조합 의사 클래스를 사용하여 상태를 전개하는:
/* 순서를 요구하지 않음 */
:link
:visited
:link:hover
:visited:hover
/* 순서를 요구함 위 2 행 이후 */
:link:active
:visited:active
/* 또는 위 2 행을 대체 순서를 요구하지 않음 */
:link:hover:active
:visited:hover:active
전개하면 중복 상태가 없어지고, 각 규칙을 엄격하게 상호 배타적으로 만들어 자연스럽게 충돌이 없어집니다
P.S. 주의: IE6-는 조합 의사 클래스를 올바르게 처리하지 못하고 마지막만 인식하므로 LVHA 가 더 널리 적용됩니다 (실제로 조합 의사 클래스의 시맨틱이 더 명확하며, "숨겨진 이상한 규칙"이 없습니다)
또한, 캐스케이딩 규칙을 사용하여 특수 효과를 구현할 수 있습니다. 예를 들어:
// lhva 를 사용하여 방문하지 않은 링크만 hover 효과가 있음
a:link {}
a:hover {}
a:visited {}
a:active {}
매우 흥미로운小技巧로, 다음과 동등합니다:
a:link:hover {}
이는 조합 의사 클래스의 시맨틱이 명확하다는 장점을 보여줍니다
아직 댓글이 없습니다