[CSS] 선택자, 결합자 및 우선 순위 (명시도)

Joowon Jang·2024년 5월 20일

CSS

목록 보기
1/3

CSS 선택자 및 결합자

스타일을 적용할 HTML 요소를 선택하기 위한 다양한 방법

기본 선택자

  • 전체 선택자 (Universal Selector) *

    모든 요소를 선택

    * {
      color: inherit;
    }
  • 요소 선택자 (Type Selector)

    HTML 요소명(태그명)을 사용하여 선택

    body { 
        margin: 0 ;
    }
  • 클래스 선택자 (Class Selector)

    클래스명을 사용하여 선택

    .fancy {
      font-weight: bold;
      text-shadow: 4px 4px 3px #77f;
    }
    
    ul.menu{
        margin: 0;
        padding-left: 0;
    }
  • 아이디 선택자 (ID Selector)

    요소의 아이디 명을 사용하여 선택

    #demo {
      border: red 2px solid;
    }
  • 속성 선택자 (Attribute Selector)

    요소의 속성의 유뮤나 속성 값의 조건에 따라 스타일을 적용

    [lang="en"] {
      font-family: Helvetica;
    }
    
    /* a 요소의 href 속성 값이 "https://"로 시작하는 경우 */
    a[href^="https://"] {
      background: url("../assets/images/external-link.png") no-repeat 100% 0;
        padding-right: 30px;
    }
    
    /* a 요소의 href 속성 값이 ".pdf"로 끝나는 경우 */
    a[href$=".pdf"] {
      font-weight: 700;
    }

그룹 선택자

  • 선택자 목록 (Selector List)

    여러개의 선택자를 쉼표로 구분하여 동일한 스타일을 적용

    h1, h2, h3, h4, h5, h6 { 
        font-weight: 400; 
    }

결합자

  • 복합 결합자 (Compound Combinator)

    두 개 또는 그 이상의 선택자를 조합하여, 두 선택자를 모두 포함한 요소에 해당 스타일 적용
.menu.selected {
	color: #ccc;
}
  • 자손 결합자 (Descendant Combinator)

    두 개 또는 그 이상의 선택자를 조합하여, 가장 마지막 선택자의 조상이 존재할 경우 해당 선택자에 스타일을 적용

    .navigation .menu li{
        color: #ccc;
    }

    중첩패턴

    .navigation {
      .menu {
        li {
        	color: #ccc;
        }
      }
    }
  • 자식 결합자 (Child Combinator)

    두 개 또는 그 이상의 선택자를 조합하여, 가장 마지막 선택자의 부모 요소가 존재할 경우 해당 선택자에 스타일을 적용

    .menu > li {
      margin: 0;
    }
  • 일반 형제 결합자 (General Sibling Combinator)

    두 개의 선택자 사이에 위치하여 뒤쪽 선택자의 요소와 앞쪽 선택자 요소의 부모 요소가 같고, 뒤쪽 선택자의 요소가 뒤에 위치할 때 선택
    두 요소가 서로 붙어있을 필요는 없다.

    /* img 요소와 부모 요소가 같은 (형제 레벨) p 요소 */
    img ~ p {
      color: red;
    }
    
  • 인접 형제 결합자 (Adjacent Sibling Combinator)

    앞에서 지정한 요소의 바로 다음에 위치하는 형제 요소만 선택

    /* img 요소 바로 뒤에 위치한 p 요소 */
    img + p {
      font-weight: bold;
    }

가상(의사) 요소/클래스

  • 가상 요소 (Pseudo Elements)

    선택자에 추가하는 키워드로, 선택한 요소의 일부분에만 스타일을 적용
    예를 들어 ::first-line, ::first-letter 등의 가상 요소 선택자를 이용하면 첫번째 줄이나 첫번째 글자 등에만 스타일을 적용할 수 있다.

    p::first-letter{
        font-size: 3rem;
        font-weight: 700;
    }
    
    p::first-line{
        background: #000;
        color: #fff;
    }
    
    ::before, ::after{
        content: "가상 요소";
    }
    
    ::selection {
      background: #373e6a;
      color: #fff;
    }
    
    input::placeholder {
      opacity: 0.5;
      color: #aaa;
    }
    
    summary::marker {
      display: none
    }
    
    ::backdrop {	
        background: rgba(0, 0, 0, 0.5);
    }
  • 가상 클래스 (Pseudo Class)

    선택자에 추가하는 키워드로, 선택한 요소가 특별한 상태일 때 선택하여 스타일을 적용
    예를 들어 마우스를 오버한 상태를 선택하려면 :hover 키워드를 키보드 초점이 포커스 된 상태를 선택하려면 :focus 키워드를 사용할 수 있다.

    :root {
        --primary-color: #373e6a;
        --secondary-color: #ccc;
        --base-color: #fff;
    }
    
    button:hover {
      background: var(--primary-color);
      color: var(--base-color);
    }
    
    a:focus{
        outline-offset: 4px;
        outline: 2px solid var(--primary-color);
    }
    
    form:focus-within {
        border: 1px solid var(--primary-color);
        border-radius: 4px;
    }
    
    button:focus-visible {
      outline: none;
      box-shadow: 1px 1px 5px var(--primary-color);
    }
    
    input:disabled {
        border: 1px solid var(--secondary-color);
        border-radius: 4px;
        color: --secondary-color;
        cursor: not-allowed;
    }
    
    input:checked {
      border: 0;
      outline: 2px solid var(--primary-color);
    }
    
    input:valid {
      background: url("../images/checked.svg") no-repeat 100% 0 / 16px 16px;
        padding-right: 36px;
    }
    
    input:invalid {
      background: url("../images/warning.svg") no-repeat 100% 0 / 16px 16px;
        padding-right: 36px;
    }
    
    li:first-child {
        margin-top: 16px 0 0 0;
    }
    
    li:nth-child(n+2) {
        margin: 8px 0;
    }
    
    li:last-child {
        margin-top: 0 0 16px 0;
    }

우선 순위

상속 (Inheritance)

CSS에서 상속은 요소에 속성 값이 따로 지정되어 있지 않은 경우 발생
이때 속성 값은 기본적으로 부모 요소의 Computed Value로 설정되며 상속되지 않는 속성의 경우는 기본적으로 속성의 초기값으로 설정됨.


명시도(Specificity)와 우선 순위

CSS에서는 하나의 요소에 여러 스타일이 겹침(Cascade) 경우, 명시도(Specificity)가 높은 선택자의 스타일이 적용된다. 명시도(Specificity)는 선택자의 우선 순위를 결정하는 방법으로, 다음과 같은 규칙에 의해 결정된다.

  • A: 아이디 선택자의 명시성 값으로, 선택자의 구성에 id가 사용된 횟수
  • B: 클래스 선택자의 명시성 값으로, 선택자에 class가 사용된 횟수
  • C: 요소 선택자와 가상 요소의 명시성 값으로 선택자 구성에 요소와 가상 요소가 사용된 횟수
  • 전체 선택자(universal selector)는 명시성 값을 가지지 않음.
  • 부정 선택자(Negation pseudo-class(:not)) 안에 포함된 선택자는 다른 선택자와 같은 방법으로 명시성을 계산하지만, 부정 선택자 자체는 예외적으로 명시성 값을 가지지 않음.(:not, :is, :where 등 예외)
  • 가상 요소(Pseudo-element)는 명시성이 요소 선택자와 같고 가상 클래스(Pseudo-class)는 클래스 선택자와 명시성이 같음.
  • 결합자나 선택자 그룹은 명시성에 영향을 끼치지 않음.
  • 최종적인 명시성 값은 A-B-C의 숫자를 연속으로 나열한 값으로, 이 숫자 값이 클수록 우선순위가 높다.

명시도 예시

예외

  • !important 예외

    CSS 속성에 !important를 선언하면 최우선순위로 해당 스타일이 적용된다.
    사용을 지양하는 것이 좋지만, JS로 이벤트를 다룰 때 사용하는 등 효율적인 사용법이 있다.

명시도가 같은 경우 우선순위

  1. 복합 결합자 (Compound Combinator)
    예: .a.b (명시도: 0-2-0)
    우선순위가 가장 높다.

  2. 자식 결합자 (Child Combinator)
    예: .a > .b (명시도: 0-2-0)
    명시도가 두 클래스 선택자와 동일하지만, 특정한 관계를 지정하여 명시도를 높인다.

  3. 자손 결합자 (Descendent Combinator)
    예: .a .b (명시도: 0-2-0)
    자식 결합자와 동일한 명시도를 가지지만, 더 넓은 범위에 적용된다.

  4. 일반 형제 결합자 (general-sibling-combinator)
    예: .a ~ .b (명시도: 0-2-0)
    자손 결합자와 동일한 명시도를 가지지만, 형제 요소에 대해 적용된다.

  5. 인접 형제 결합자 (adjacent-sibling-combinator)
    예: .a + .b (명시도: 0-2-0)
    자손 결합자와 동일한 명시도를 가지지만, 바로 인접한 형제 요소에 대해 적용된다.

+ @media 규칙으로 선언한 스타일도 같은 우선순위를 가진다.
나는 @media 규칙으로 선언한 스타일은 !important 처럼 가장 우선으로 적용된다고 생각했는데, 동일한 우선순위를 가지기 때문에 명시도와 우선 순위(중첩단계까지) 신경을 써줘야한다...

profile
깊이 공부하는 웹개발자

0개의 댓글