CSS 선택 기 우선 순위 계산 깊이 이해
19090 단어 css
최신 Selector Level 3 규범 에서:
질문:
1. 선택 기의 전체 우선 순 위 는 어떻게 계산 합 니까? 인터넷 에서 말 한 a * 1000 + b * 100 + c * 10 + d 와 같 습 니까?
답: 아니요.이런 대답 은 분명히 문 의 를 바라 보고 의 미 를 가 진 것 이다.4 급 (a, b, c, d) 간 은 단순 한 더하기 관계 가 아니다.같은 등급 (예 를 들 어 a 대 a) 의 것 만 비교 가능 한 관 계 를 가진다.
분석:
다음은 웹 키 트 의 웹 코어 에서 우선 순위 계산 에 관 한 코드 http://trac.webkit.org/browser/trunk/Source/WebCore/css/CSSSelector.cpp 입 니 다.
)
unsigned CSSSelector::specificity() const
{
// make sure the result doesn't overflow
static const unsigned maxValueMask = 0xffffff; // , :idMask + classMask + elementMak = 16777215
static const unsigned idMask = 0xff0000; // ID , :(16*16+16)*16^4=16711680
static const unsigned classMask = 0xff00; // class( 、 ) , :(16*16+16)*16^2=65280
static const unsigned elementMask = 0xff; // , :16*16+16=255
if (isForPage())
return specificityForPage() & maxValueMask;
unsigned total = 0;
unsigned temp = 0;
for (const CSSSelector* selector = this; selector; selector = selector->tagHistory()) {
temp = total + selector->specificityForOneSelector();
// Clamp each component to its max in the case of overflow.
if ((temp & idMask) < (total & idMask)) // ID
total |= idMask; // ID ID ,
else if ((temp & classMask) < (total & classMask))
total |= classMask;
else if ((temp & elementMask) < (total & elementMask))
total |= elementMask;
else
total = temp;
}
return total;
}
inline unsigned CSSSelector::specificityForOneSelector() const
{
// FIXME: Pseudo-elements and pseudo-classes do not have the same specificity. This function
// isn't quite correct.
switch (m_match) {
case Id:
return 0x10000; // ID
case PseudoClass:
// FIXME: PsuedoAny should base the specificity on the sub-selectors.
// See http://lists.w3.org/Archives/Public/www-style/2010Sep/0530.html
if (pseudoClassType() == PseudoClassNot && selectorList())
return selectorList()->first()->specificityForOneSelector();
FALLTHROUGH;
case Exact:
case Class:
case Set:
case List:
case Hyphen:
case PseudoElement:
case Contain:
case Begin:
case End:
return 0x100; // class
case Tag:
return (tagQName().localName() != starAtom) ? 1 : 0; //
case Unknown:
return 0;
}
ASSERT_NOT_REACHED();
return 0;
}
위의 코드 를 통 해 알 수 있 듯 이 웹 키 트 에서 a 급 선택 기 ("style" 속성의 스타일 규칙) 는 우선 순위 연산 과정 에 참여 하지 않 습 니 다.b 급 (ID 선택 기), c 급 (class 선택 기), d 급 (요소 선택 기) 에 대해 서 는 각 단계 마다 자신의 최대 치 (최대 수 255) 가 있 고 초과 시 최대 치 (최대 수) 를 적용 합 니 다.b 급 최대 치 는 0xff 0000 (16711680) 이 고 가중치 는 0x 1000 (65536) 이 며 수량 이 256 을 초과 할 때 도 최대 치 를 사용 합 니 다.c 급, d 급 이 비슷 하 다.따라서 낮은 등급 이 일정 수 를 초과 한 후에 높 은 등급 이 1 단계 로 올 라 가 커버 되 는 상황 은 존재 하지 않 는 다.선택 기 그룹 (em: \ # a. d div) 에서 모든 선택 기의 더하기 와 167777215 를 초과 하지 않 습 니 다.demo: http://jsbin.com/duker/2 。맞다!important, webkit 는 다른 경로 (있 습 니 다! important 스타일 규칙 은 없 는 것 보다 큽 니 다! important 스타일 규칙 은 동시에 있 습 니 다! important 속성 을 가 질 때 만 선택 기의 전체 우선 순 위 를 비교 할 수 있 습 니 다).전체적으로 웹 키 트 에서!important>inline style>ID>class>tag。
웹 키 트 는
http://trac.webkit.org/changeset/130444/trunk/Source/WebCore/css/CSSSelector.cpp 이번 수정 에 우선 순위 가 넘 치 는 처리 (chrome 발표 버 전이 빠 르 고 올 해 는 blink 로 바 뀌 었 습 니 다. chrome 은 모두 특수성 (우선 순위) 계산 기준 을 지 켰 다 고 볼 수 있 습 니 다).
타임 스탬프: 2012 - 10 - 04 19: 04: 44
20 개 월 전) 저자: commt [email protected]메시지:
선택 기 특수성 클래스 가 높 은 클래스 로 넘 침 https://bugs.webkit.org/show_bug.cgi?id=98295
Patch by Tab Atkins < [email protected] > on 2012-10-04Reviewed by Eric Seidel.
이번에 추 가 된 패 치 는 CSS 선택 기의 특수성 에 대해 넘 침 정책 을 추가 하기 위 한 것 입 니 다.
이전에 우 리 는 각 유형의 특수성 유출 문 제 를 검사 하지 않 았 다.원본 정책 은 각 분 류 를 하나의 바이트 (2 ^ 8 = 256) 로 저장 한 다음 에 전체적으로 기호 없 는 정수 가 존재 합 니 다.이렇게 되면 256 개의 같은 유형의 단일 선택 기 는 1 개의 높 은 유형의 선택 기 와 같다.그러나 이 는 선택 기의 특수성 규칙 을 위반 해 스타일 규칙 정렬 에 문제 가 생 겼 다.
Tests: /fast/selectors/specificity-overflow.html
(WebCore::CSSSelector::specificity):
mozilla 에서 우선 순위 계산 에 관 한 코드 (주 소 는?
http://hg.mozilla.org/mozilla-central/file/7297dedf2416/layout/style/StyleRule.cpp (472 줄 - 537 줄):
int32_t nsCSSSelector::CalcWeightWithoutNegations() const
{
int32_t weight = 0;
#ifdef MOZ_XUL
MOZ_ASSERT(!(IsPseudoElement() &&
PseudoType() != nsCSSPseudoElements::ePseudo_XULTree &&
mClassList),
"If non-XUL-tree pseudo-elements can have class selectors "
"after them, specificity calculation must be updated");
#else
MOZ_ASSERT(!(IsPseudoElement() && mClassList),
"If pseudo-elements can have class selectors "
"after them, specificity calculation must be updated");
#endif
MOZ_ASSERT(!(IsPseudoElement() && (mIDList || mAttrList)),
"If pseudo-elements can have id or attribute selectors "
"after them, specificity calculation must be updated");
if (nullptr != mCasedTag) {
weight += 0x000001;
}
nsAtomList* list = mIDList;
while (nullptr != list) {
weight += 0x010000;
list = list->mNext;
}
list = mClassList;
#ifdef MOZ_XUL
// XUL tree pseudo-elements abuse mClassList to store some private
// data; ignore that.
if (PseudoType() == nsCSSPseudoElements::ePseudo_XULTree) {
list = nullptr;
}
#endif
while (nullptr != list) {
weight += 0x000100;
list = list->mNext;
}
// FIXME (bug 561154): This is incorrect for :-moz-any(), which isn't
// really a pseudo-class. In order to handle :-moz-any() correctly,
// we need to compute specificity after we match, based on which
// option we matched with (and thus also need to try the
// highest-specificity options first).
nsPseudoClassList *plist = mPseudoClassList;
while (nullptr != plist) {
weight += 0x000100;
plist = plist->mNext;
}
nsAttrSelector* attr = mAttrList;
while (nullptr != attr) {
weight += 0x000100;
attr = attr->mNext;
}
return weight;
}
int32_t nsCSSSelector::CalcWeight() const
{
// Loop over this selector and all its negations.
int32_t weight = 0;
for (const nsCSSSelector *n = this; n; n = n->mNegations) {
weight += n->CalcWeightWithoutNegations();
}
return weight;
}
웹 키 트 와 마찬가지 로 inline style 요 소 는 계산 에 포함 되 지 않 습 니 다.b 급 (ID), c 급 (class), d 급 (tag) 의 최대 값 과 최소 값 도 웹 키 트 와 일치 합 니 다.다른 것 은 mozilla 에서 같은 유형의 선택 기 를 최대 치 로 제어 하지 않 고 결 과 를 직접 추가 하 는 것 이다.이렇게 되면 같은 등급 의 선택 기 수가 255 보다 많 을 때 한 단계 높 아 지 는 것, 즉 결과 가 넘 치 는 문제 가 발생 할 수 있다.또한 전체 선택 기 그룹의 우선 순위 계산 은 웹 키 트 와 유사 한 비트 와 연산 이 없 기 때문에 결과 가 넘 치지 않도록 보장 합 니 다. 간단 한 더하기 만 있 으 면 mozilla 에서 넘 치 는 문제 가 발생 할 수 있 습 니 다.
IE 는 코드 를 읽 을 수 없 기 때문에 IE 시리즈 에 대해 서 는 데모 테스트 방법 으로 문 제 를 확인 할 수 밖 에 없다.모든 IE 시리즈 (q, s) 에서 표현 은 mozilla 와 일치 합 니 다.최신 IE 11 포함.
주: CSS 선택 기 는 계승 성 이 있 습 니 다.
test text
모든 브 라 우 저 에서 텍스트 는 p {font - size: 24px;} 을 사용 합 니 다.이 문장 을 지우 면 * {font - size: 40px;}, * p 를 포함 합 니 다.(계승 스타일 은 우선 순위 가 없습니다)
결론:
1. 우선 순위 계산 시 등급 을 뛰 어 넘 는 문 제 를 주의해 야 한다.
2. 우선 순위 계산 은 inline style 과!important;
3. 우선 순위 계산 은 같은 유형 만 비교 할 수 있 습 니 다 (일반적으로 255 개 이상 의 같은 선택 기 를 정의 하 는 사람 이 없습니다).
참고 로 인용 하 다
stackoverflow 위의 대답 으로 이 글 을 끝 냅 니 다.
I am currently using the book CSS Mastery: Advanced Web Standards Solutions .
Chapter 1, page 16 says:
To calculate how specific a rule is, each type of selector is assigned a numeric value. The specificity of a rule is then calculated by adding up the value of each of its selectors. Unfortunately, specificity is not calculated in base 10 but a high, unspecified, base number. This is to ensure that a highly specific selector, such as an ID selector, is never overridden by lots of less specific selectors, such as type selectors.
참고 글:
http://trac.webkit.org/browser/trunk/Source/WebCore/css/CSSSelector.cpp
http://hg.mozilla.org/mozilla-central/file/17c65d32c7b8/layout/style/StyleRule.cpp#l521
브 라 우 저의 작업 원리: 신식 웹 브 라 우 저의 배후 폭로
KB 005: CSS 레이 어드
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
장치 너비가 특정 너비보다 크고 특정 너비보다 작을 때 웹 페이지 CSS 스타일을 변경하는 방법은 무엇입니까?장치 너비가 특정 너비보다 크고 특정 너비보다 작을 때 웹 페이지 CSS 스타일을 변경하려면 @media의 미디어 쿼리 구문을 사용한 다음 구문을 작성하여 스타일의 최소 너비를 정의해야 합니다. 적용된 후 and라는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.