Front-End/HTML,CSS

style lint selector-max-type: 0은 μ–΄λ–»κ²Œ μž‘λ™ν• κΉŒ?

Splin 2024. 10. 27.

 

0. κ°œμš”

업무 μ½”λ“œλ¦¬λ·° 쀑 λ™λ£ŒλΆ„μ΄ 클릭 κ°€λŠ₯ 여뢀에 따라 λ‹€λ₯Έ μŠ€νƒ€μΌμ΄ ν•„μš”ν•˜μ—¬ λ‹€μŒκ³Ό 같은 μ½”λ“œλ₯Ό μ œμ‹œν•΄μ£Όμ…¨λŠ”λ°, style lint selector-max-type: 0에 κ±Έλ € μ—λŸ¬κ°€ λ°œμƒν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

selector-max-type 룰은 νƒœκ·Έ μ„ νƒμžλ₯Ό μ‚¬μš©ν•¨μœΌλ‘œ μΈν•΄μ„œ μ—¬λŸ¬ μ»΄ν¬λ„ŒνŠΈκ°€ μ€‘μ²©λ˜μ–΄ μžˆμ„ λ•Œ ν•˜μœ„ μ»΄ν¬λ„ŒνŠΈμ˜ μŠ€νƒ€μΌμ— 영ν–₯을 μ£ΌλŠ” κ±Έ μ°¨λ‹¨ν•˜κΈ° μœ„ν•΄μ„œ μ μš©ν•΄ λ‘μ—ˆμŠ΅λ‹ˆλ‹€
&__content {
  background-color: #{$opacity-gray-16};
  
  &:where(button) {
    &:hover {
      background-color: #{$opacity-gray-24};
    }
    &:active {
      background-color: #{$opacity-gray-32};
    }
  }
}

κ·Έλž˜μ„œ μ•„λž˜μ™€ 같은 방법을 λ‹€μ‹œ μ œμ‹œν•΄μ£Όμ…¨λŠ”λ°, 기쑴의 &:where(button)μ™€μ˜ 차이λ₯Ό μ •ν™•νžˆ μΈμ§€ν•˜μ§€ λͺ»ν•˜μ—¬ selector-max-type에 λŒ€ν•΄ μ•Œμ•„λ³΄λ €κ³  ν•©λ‹ˆλ‹€.

&__content {
  background-color: #{$opacity-gray-16};
  
  &:where(button#{&}) { // buttonμ—μ„œ button#{&}둜 변경됨
    &:hover {
      background-color: #{$opacity-gray-24};
    }
    &:active {
      background-color: #{$opacity-gray-32};
    }
  }
}

 

1. 원인 μ ‘κ·Ό 방법

λ¨Όμ € 항상 κ·Έλ ‡λ“― μŠ€νƒ€μΌλ¦°νŠΈ κ³΅μ‹λ¬Έμ„œ(selector-max-type docs)λΆ€ν„° μ‚΄νŽ΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

선택기 λͺ©λ‘μ˜ 각 μ„ νƒκΈ°λŠ” κ°œλ³„μ μœΌλ‘œ ν‰κ°€λœλ‹€?!

곡식 λ¬Έμ„œ μ΄ˆλ°˜λΆ€λ₯Ό 보면 λ‹€μŒκ³Ό 같은 문ꡬλ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€

This rule resolves nested selectors before counting the number of type selectors. Each selector in a selector list is evaluated separately.

μ—¬κΈ°μ„œ Each selector in a selector list is evaluated separately. (μ„ νƒμž λͺ©λ‘μ˜ 각 μ„ νƒμžλŠ” κ°œλ³„μ μœΌλ‘œ ν‰κ°€λ©λ‹ˆλ‹€.) λΌλŠ” 문ꡬ가 λˆˆμ— λ•λ‹ˆλ‹€.

μ–΄λ–€ μ„ νƒμžκ°€ κ°œλ³„μ μœΌλ‘œ ν‰κ°€λ˜λŠ”μ§€ μ•Œμ•„λ³΄κΈ° 전에 μ„ νƒμžμ˜ μ’…λ₯˜κ°€ 무엇이 μžˆλŠ”μ§€ κ°„λ‹¨νžˆ μ•Œμ•„λ³΄λ„λ‘ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

μ„ νƒμžμ˜ μ’…λ₯˜

μ„ νƒμžμ˜ μ’…λ₯˜λŠ” MDN에도 잘 λ‚˜μ™€μžˆλŠ”λ°, κ°„λ‹¨νžˆ λ‚˜μ—΄ν•˜μžλ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

 

    1. κΈ°λ³Έ μ„ νƒμž
      1. 전체 μ„ νƒμž: λͺ¨λ“  μš”μ†Œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€.(ex. *, ns|*, *|*)
      2. μš”μ†Œ μ„ νƒμž: νŠΉμ • HTML μš”μ†Œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€. (ex. div, p, h1)
      3. 클래슀 μ„ νƒμž: νŠΉμ • ν΄λž˜μŠ€κ°€ μžˆλŠ” μš”μ†Œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€.
      4. ID μ„ νƒμž: νŠΉμ • IDκ°€ μžˆλŠ” μš”μ†Œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€. (ex. #id)
      5. 속성 μ„ νƒμž: νŠΉμ • 속성을 κ°€μ§„ μš”μ†Œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€. (ex. input[type="text"])
    2. κ·Έλ£Ή μ„ νƒμž: μ—¬λŸ¬ μ„ νƒμžλ₯Ό μ‰Όν‘œλ‘œ κ΅¬λΆ„ν•˜μ—¬ ν•œ λ²ˆμ— μŠ€νƒ€μΌμ„ μ μš©ν•©λ‹ˆλ‹€. (ex. h1, h2, p)
    3. μžμ‹ 및 후손 μ„ νƒμž
      1. μžμ‹ μ„ νƒμž: νŠΉμ • μš”μ†Œμ˜ 직계 μžμ‹μ„ μ„ νƒν•©λ‹ˆλ‹€. (ex. ul > li)
      2. 후손 μ„ νƒμž: νŠΉμ • μš”μ†Œμ˜ λͺ¨λ“  후손을 μ„ νƒν•©λ‹ˆλ‹€. (ex. div p)
      3. 일반 ν˜•μ œ μ„ νƒμž: 첫 번째 μš”μ†Œλ₯Ό λ’€λ”°λ₯΄λ©΄μ„œ 같은 λΆ€λͺ¨λ₯Ό κ³΅μœ ν•˜λŠ” 두 번째 μš”μ†Œλ₯Ό λͺ¨λ‘ μ„ νƒν•©λ‹ˆλ‹€. (ex. p ~ span)
      4. 인접 ν˜•μ œ μ„ νƒμž: 첫 번째 μš”μ†Œμ˜ λ°”λ‘œ 뒀에 μœ„μΉ˜ν•˜λ©΄μ„œ 같은 λΆ€λͺ¨λ₯Ό κ³΅μœ ν•˜λŠ” 두 번째 μš”μ†Œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€. (ex. h2 + p)
      5. μ—΄ μ„ νƒμž: 첫 번째 μš”μ†Œμ— μ†ν•˜λŠ” λͺ¨λ“  두 번째 μš”μ†Œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€. (ex. col || td)
    4. μƒνƒœ μ„ νƒμž
      1. μ˜μ‚¬ 클래슀 μ„ νƒμž: νŠΉμ • μƒνƒœμ— μžˆλŠ” μš”μ†Œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€. (ex. a:hover, input:focus, li:first-child)
      2. μ˜μ‚¬ μš”μ†Œ μ„ νƒμž: μš”μ†Œμ˜ νŠΉμ • 뢀뢄을 μ„ νƒν•©λ‹ˆλ‹€. (ex. p::first-line, ::before, ::after)
    5. 볡합 μ„ νƒμž: μ—¬λŸ¬ μ„ νƒμžλ₯Ό μ‘°ν•©ν•˜μ—¬ 더 ꡬ체적으둜 μ„ νƒν•©λ‹ˆλ‹€. (ex. div.classname > p#idname)

 

2. μ—λŸ¬ λ°œμƒ/λ―Έλ°œμƒ 경우 비ꡐ

μ„ νƒμžμ˜ μ’…λ₯˜μ— λŒ€ν•΄μ„œλ„ μ•Œμ•„λ΄€μœΌλ‹ˆ, 이제 μ•„λž˜μ˜ μ—λŸ¬ λ°œμƒ/λ―Έλ°œμƒμ˜ 두 κ°€μ§€ 경우λ₯Ό κ°€μ Έμ™€μ„œ λΉ„κ΅ν•΄λ΄€μŠ΅λ‹ˆλ‹€.

.content {
  ...
  
  // 1. μ„±κ³΅ν•œ 경우
  &:where(button#{&}) {
    ...
  }
  
  // 2. μ‹€νŒ¨ν•œ 경우
  &:where(button) { 
    ...
  }
}

λ¨Όμ € 1번과 μ‹€νŒ¨ν•œ 2λ²ˆμ„ λ‹€μŒκ³Ό 같이 컴파일된 μ½”λ“œλ‘œ λ³€κ²½ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

  1. μ„±κ³΅ν•œ 경우: &:where(button#{&}) -> .content:where(button.content)
  2. μ‹€νŒ¨ν•œ 경우: &:where(button) -> .content:where(button)

μ„ νƒμžλŠ” κ°œλ³„μ μœΌλ‘œ ν‰κ°€λœλ‹€κ³  ν–ˆκΈ°μ— μ„±κ³΅ν•œ κ²½μš°λŠ” μ˜μ‚¬ 클래슀 μ„ νƒμžλ‘œ 이루어져 있고 μ˜μ‚¬ 클래슀 λ‚΄λΆ€λŠ” 클래슀 μ„ νƒμžλ‘œ 이루어져 있기 λ•Œλ¬Έμ— μ„±κ³΅ν•œ 경우의 μ„ νƒμžλŠ” μ˜μ‚¬ 클래슀 μ„ νƒμž + 클래슀 μ„ νƒμžλ‘œ λ³Ό 수 있고, μ„ νƒμž μ’…λ₯˜κ°€ μ€‘λ³΅λ˜μ§€ μ•ŠκΈ°μ— 성곡할 수 μžˆμ—ˆλ˜ κ²ƒμž…λ‹ˆλ‹€.

그런데, μ΄μƒν•˜κ²Œ μ‹€νŒ¨ν•œ κ²½μš°λ„ μ˜μ‚¬ 클래슀 μ„ νƒμž + νƒœκ·Έ(μš”μ†Œ) μ„ νƒμžλ‘œ 이루어져 μžˆμ–΄ "κ°œλ³„μ μœΌλ‘œ μ„ νƒμžκ°€ ν‰κ°€λœλ‹€λ©΄ 성곡해야 ν•˜λŠ” 게 μ•„λ‹Œκ°€?" λΌλŠ” 의문이 μƒκΈ°κ²Œ λ©λ‹ˆλ‹€.

 

3. selector-max-type: 0은 클래슀 μ„ νƒμžλ§Œ ν—ˆμš©ν•œλ‹€

μœ„ μ˜λ¬Έμ„ κ°€μ§€κ³  "selector-max-type이 0이면 λ‹€λ₯΄κ²Œ ν‰κ°€λ˜λŠ” 것일 μˆ˜λ„ μžˆκ² λ‹€"λΌλŠ” 생각을 κ°€μ§€κ³  ν•΄λ‹Ή λ¬Έμ œμ— λŒ€ν•΄μ„œ μ°Ύμ•„λ΄€λŠ”λ°, 곡식 λ¬Έμ„œλ‚˜ κ΅¬κΈ€λ§μœΌλ‘œ 닡이 잘 λ‚˜μ˜€μ§€ μ•Šμ•„ GPTμ—κ²Œ λ‹€μŒμ˜ 닡을 얻을 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

selector-max-type이 0이면 클래슀 μ„ νƒμžλ§Œ ν—ˆμš©ν•œλ‹€

μœ„ μ„€λͺ…을 ν† λŒ€λ‘œ μ΄μ œκΉŒμ§€μ˜ λ¬Έμ œμ— λŒ€μž…μ„ 해보면 μ‹€νŒ¨ν•œ 경우의 원인이 λͺ…ν™•ν•˜κ²Œ λ“œλŸ¬λ‚˜κ²Œ λ©λ‹ˆλ‹€.

  1. μ„±κ³΅ν•œ 경우: &:where(button#{&}) -> .content:where(button.content) -> μ˜μ‚¬ 클래슀 μ„ νƒμž + 클래슀 μ„ νƒμž
  2. μ‹€νŒ¨ν•œ 경우: &:where(button) -> .content:where(button) -> μ˜μ‚¬ 클래슀 μ„ νƒμž + νƒœκ·Έ(μš”μ†Œ) μ„ νƒμž

μ‹€νŒ¨ν•œ κ²½μš°μ—λŠ” νƒœκ·Έ(μš”μ†Œ) μ„ νƒμžκ°€ ν¬ν•¨λ˜μ–΄ 있기 λ•Œλ¬Έμ— stylelint seleoctor-max-type: 0에 κ±Έλ € μ—λŸ¬κ°€ λ°œμƒν–ˆλ˜ κ²ƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜, κ³΅μ‹λ¬Έμ„œμ—λŠ” κ΄€λ ¨ λ‚΄μš©μ΄ λ”°λ‘œ μ—†μ–΄μ„œ GPT만 λ―Ώκ³  μ΄λŒ€λ‘œ 결둠을 λ‚΄λ²„λ¦¬κΈ°μ—λŠ” 찝찝해 μœ„ μ„€λͺ…을 기반으둜 ν…ŒμŠ€νŠΈν•΄λ΄€λŠ”λ°, νƒœκ·Έ(μš”μ†Œ) μ„ νƒμžκ°€ ν¬ν•¨λ˜μ–΄ 있으면 style lint errorλ₯Ό λ°œμƒμ‹œν‚€λŠ” 것을 ν™•μΈν•˜μ˜€μŠ΅λ‹ˆλ‹€.

 

4. 마치며

λ™λ£Œμ˜ ν”Όλ“œλ°±μ„ ν†΅ν•΄μ„œ selector-max-typeκ³Ό μ„ νƒμžμ˜ μ’…λ₯˜μ— λŒ€ν•΄μ„œ μ•Œμ•„λ΄€λŠ”λ°, μ‚¬λ‚΄μ—μ„œ 적극적인 μ½”λ“œ 리뷰λ₯Ό 톡해 λͺ°λžλ˜ 사싀을 μ•Œκ²Œ 되고 λ™λ£Œμ˜ 쒋은 μ½”λ”© μŠ€νƒ€μΌλ„ ν‘μˆ˜ν•˜λ©΄μ„œ μ„œλ‘œμ—κ²Œ 쒋은 μ‹œλ„ˆμ§€λ₯Ό μΌμœΌν‚€κ³  μžˆλŠ” 것 κ°™μ•„ μš”μ¦˜μ€ 만쑱슀러운 νšŒμ‚¬ μƒν™œμ„ ν•΄λ‚˜κ°€κ³  μžˆμŠ΅λ‹ˆλ‹€.

쒋은 λ™λ£Œκ°€ μžˆμŒμ— κ°μ‚¬ν•˜κ³  μƒˆμ‚Ό GPT의 λ“±μž₯도 생산λ ₯에 큰 도움이 λœλ‹€λŠ” κ±Έ λ‹€μ‹œ ν•œ 번 κΉ¨λ‹«κ²Œ λ˜λ„€μš”.

λŒ“κΈ€