πŸ’» FE/πŸ“ HTML & CSS

πŸ’Ύ CSS :not()κ³Ό :has()의 μ‘°ν•©

Roy Miller 2025. 3. 12. 14:02

1. :not() μ˜μ‚¬ 클래슀 (Negation Pseudo-class)

  • :not()은 νŠΉμ • 쑰건을 λ§Œμ‘±ν•˜μ§€ μ•ŠλŠ” μš”μ†Œλ₯Ό 선택함.
  • κ΄„ν˜Έ μ•ˆμ— μ„ νƒμžλ₯Ό λ„£μ–΄ ν•΄λ‹Ή μ„ νƒμžμ— ν•΄λ‹Ήν•˜μ§€ μ•ŠλŠ” μš”μ†Œμ—λ§Œ μŠ€νƒ€μΌ μ μš©ν•¨.
μ„ νƒμž:not(μ œμ™Έν• _μ„ νƒμž) {
  /* μŠ€νƒ€μΌ */
}

 

 

μ œμ™Έν•  μ„ νƒμžμ— λ“€μ–΄κ°ˆ 수 μžˆλŠ” 것:

  • λ‹¨μˆœ μ„ νƒμž (Simple Selector):
    • νƒ€μž… μ„ νƒμž (Type Selector): div, p, span, a λ“± HTML νƒœκ·Έ 이름
    • 클래슀 μ„ νƒμž (Class Selector): .my-class
    • ID μ„ νƒμž (ID Selector): #my-id
    • 전체 μ„ νƒμž (Universal Selector): *
    • 속성 μ„ νƒμž (Attribute Selector): [type="text"], [data-value] λ“±
    • 일뢀 μ˜μ‚¬ 클래슀 (Pseudo-class): :first-child, :last-child, :nth-child(), :checked, :enabled, :disabled λ“± (단, :not() μžμ‹ μ€ 쀑첩 λΆˆκ°€)

μ œμ™Έν•  μ„ νƒμžμ— λ“€μ–΄κ°ˆ 수 μ—†λŠ” 것:

  • 볡합 μ„ νƒμž (Combinator): > (μžμ‹), + (인접 ν˜•μ œ), ~ (일반 ν˜•μ œ), 곡백 (ν•˜μœ„)
  • μ˜μ‚¬ μš”μ†Œ (Pseudo-element): ::before, ::after, ::first-line λ“±
  • :not() μžμ‹ : :not(:not(...))κ³Ό 같이 μ€‘μ²©ν•΄μ„œ μ‚¬μš©ν•  수 μ—†μŒ
  • :has(): μ‚¬μš©ν•  수 μ—†μŒ.

 

/* <p> μš”μ†Œ 쀑 classκ°€ "special"이 *μ•„λ‹Œ* μš”μ†Œμ— μŠ€νƒ€μΌ 적용 */
p:not(.special) {
  color: blue;
}

/* type이 "submit"이 *μ•„λ‹Œ* <input> μš”μ†Œμ— μŠ€νƒ€μΌ 적용 */
input:not([type="submit"]) {
  border: 1px solid gray;
}

/* 첫 번째 μžμ‹ μš”μ†Œκ°€ *μ•„λ‹Œ* <li> μš”μ†Œμ— μŠ€νƒ€μΌ 적용 */
li:not(:first-child) {
  margin-left: 10px;
}

/* <a> μš”μ†Œ 쀑 hover μƒνƒœκ°€ *μ•„λ‹Œ* μš”μ†Œμ— μŠ€νƒ€μΌ 적용*/
a:not(:hover){
    text-decoration: none;
}

 

2. :has() μ˜μ‚¬ 클래슀

  • :has()λŠ” νŠΉμ • 쑰건을 λ§Œμ‘±ν•˜λŠ” μš”μ†Œλ₯Ό ν¬ν•¨ν•˜λŠ” λΆ€λͺ¨ μš”μ†Œλ₯Ό 선택함.
  • κ΄„ν˜Έ μ•ˆμ— μ„ νƒμžλ₯Ό λ„£μ–΄, ν•΄λ‹Ή μ„ νƒμžμ— ν•΄λ‹Ήν•˜λŠ” μžμ‹ λ˜λŠ” ν•˜μœ„ μš”μ†Œλ₯Ό ν•˜λ‚˜ 이상 κ°€μ§€λŠ” λΆ€λͺ¨ μš”μ†Œμ— μŠ€νƒ€μΌμ„ μ μš©ν•¨.
μ„ νƒμž:has(포함_μ—¬λΆ€λ₯Ό_검사할_μ„ νƒμž) {
  /* μŠ€νƒ€μΌ */
}

 

포함 μ—¬λΆ€λ₯Ό 검사할 μ„ νƒμžμ— λ“€μ–΄κ°ˆ 수 μžˆλŠ” 것:

  • :has() μ•ˆμ—λŠ” 거의 λͺ¨λ“  μ’…λ₯˜μ˜ μ„ νƒμžλ₯Ό μ‚¬μš©ν•  수 있음.
  • λ‹¨μˆœ μ„ νƒμžλΏλ§Œ μ•„λ‹ˆλΌ 볡합 μ„ νƒμž, μ˜μ‚¬ 클래슀, 심지어 λ‹€λ₯Έ :has()κΉŒμ§€λ„ (μ€‘μ²©ν•΄μ„œ) μ‚¬μš©ν•  수 있음.
/* <img> μš”μ†Œλ₯Ό *ν•˜λ‚˜ 이상 ν¬ν•¨ν•˜λŠ”* <figure> μš”μ†Œμ— μŠ€νƒ€μΌ 적용 */
figure:has(img) {
  border: 1px solid red;
}

/* classκ°€ "active"인 <li> μš”μ†Œλ₯Ό *ν•˜λ‚˜ 이상 ν¬ν•¨ν•˜λŠ”* <ul> μš”μ†Œμ— μŠ€νƒ€μΌ 적용 */
ul:has(li.active) {
  background-color: lightyellow;
}

/* <input type="checkbox"> μš”μ†Œκ°€ 체크된(:checked) μƒνƒœμΈ <label> μš”μ†Œμ— μŠ€νƒ€μΌ 적용.
   (label μ•ˆμ— input 이 μžˆλŠ” 경우) */
label:has(input[type="checkbox"]:checked) {
    font-weight: bold;
}

/* <a>μš”μ†Œ λ°”λ‘œ 뒀에 <p>μš”μ†Œκ°€ μ˜€λŠ” 경우, a에 μŠ€νƒ€μΌ 적용 */
a:has(+ p){
    color: red;
}

 

3. :not()κ³Ό :has() μ‘°ν•©

  • μ„ νƒμž:not(:has(μžμ‹μ„ νƒμž)): μ„ νƒμžμ— ν•΄λ‹Ήν•˜λŠ” μš”μ†Œ 쀑, μžμ‹ μ„ νƒμžμ— ν•΄λ‹Ήν•˜λŠ” μžμ‹/ν•˜μœ„ μš”μ†Œλ₯Ό κ°€μ§€μ§€ μ•ŠλŠ” μš”μ†Œλ₯Ό 선택.
  • μ„ νƒμž:has(:not(μžμ‹μ„ νƒμž)): μ„ νƒμžμ— ν•΄λ‹Ήν•˜λŠ” μš”μ†Œ 쀑, μžμ‹ μ„ νƒμžμ— ν•΄λ‹Ήν•˜μ§€ μ•ŠλŠ” μžμ‹/ν•˜μœ„μš”μ†Œλ₯Ό ν•˜λ‚˜λΌλ„ κ°€μ§€λŠ” μš”μ†Œ
.re-container:not(:has(#b1:hover, #b2:hover, #b3:hover)) #c1 {
    display: block;
}

 

 

  1. #b1:hover, #b2:hover, #b3:hover: #b1, #b2, #b3 쀑 μ–΄λŠ ν•˜λ‚˜λΌλ„ hover μƒνƒœμΈ μš”μ†Œλ₯Ό 찾음.
  2. :has(#b1:hover, #b2:hover, #b3:hover): 1λ²ˆμ—μ„œ 찾은 μš”μ†Œλ₯Ό ν•˜λ‚˜ 이상 ν¬ν•¨ν•˜λŠ” μš”μ†Œλ₯Ό 찾음. (re-container)
  3. .re-container:not(...): .re-container μš”μ†Œ 쀑, 2번의 쑰건에 ν•΄λ‹Ήν•˜μ§€ μ•ŠλŠ” μš”μ†Œλ₯Ό 선택함.
    1. #b1, #b2, #b3 쀑 μ–΄λŠ 것도 hover μƒνƒœκ°€ μ•„λ‹Œ 경우의 .re-containerλ₯Ό 선택.
  4. ... #c1: 3λ²ˆμ—μ„œ μ„ νƒλœ .re-container의 ν•˜μœ„ μš”μ†Œ 쀑 #c1을 선택함.
  5. display:block: μ„ νƒλœ #c1을 보이게 함.

μ–΄λ–€ λ²„νŠΌλ„ hoverλ˜μ§€ μ•Šμ€ 초기 μƒνƒœμ—μ„œλ§Œ #c1이 보이게 됨.

 

:not()κ³Ό :has()λ₯Ό μ‘°ν•©ν•˜λ©΄ "Aλ₯Ό ν¬ν•¨ν•˜μ§€ μ•ŠμœΌλ©΄μ„œ Bλ₯Ό ν¬ν•¨ν•˜λŠ” μš”μ†Œ" 와 같은 λ³΅μž‘ν•œ 쑰건을 ν‘œν˜„ν•  수 있음.