Style Sheet/CSS

๐ŸŒŸ @media๋Š” ์ด์ œ ๊ทธ๋งŒ ! ์ตœ์‹  @container ์‚ฌ์šฉ๋ฒ•

์ธํŒŒ_ 2023. 3. 24. 09:44

media-container-query

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ vs ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ๋Š” ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ์™€ ๊ฐ™์ด ๋ฌธ์„œ์˜ ์Šคํƒ€์ผ์„ ๋ฐ˜์‘ํ˜•์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋‘˜์˜ ์ž‘๋™ ๋ฐฉ์‹์€ ์œ ์‚ฌํ•˜์ง€๋งŒ, ์ฐจ์ด์ ์€ ์–ด๋Š ๊ฒƒ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘๋˜๋ƒ๋Š” ์ ์ด๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ๋Š” ๋””๋ฐ”์ด์Šค ๋˜๋Š” ๋ฏธ๋””์–ด ์œ ํ˜•์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ทฐํฌํŠธ์— ์˜ํ•ด ๋ฐ˜์‘ํ•˜์ง€๋งŒ, ์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ๋Š” ํŽ˜์ด์ง€๋‚ด์˜ ํŠน์ • ์ปดํฌ๋„ŒํŠธ ์š”์†Œ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ˜์‘ํ•œ๋‹ค.

์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ๋ ํ…๋ฐ, ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ๋Š” ๋ธŒ๋ผ์šฐ์ € ๋„ˆ๋น„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฐ˜์‘ํ•˜์ง€๋งŒ, ์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ๋Š” ๋ฌธ์„œ ๋‚ด ๊ฐ ์š”์†Œ ์˜ ํฌ๊ธฐ๋‚˜ ๋ชจ์–‘์— ๋”ฐ๋ผ ๋ฐ˜์‘ํ˜• ์ฟผ๋ฆฌ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ์ƒ์œ„ ํ˜ธํ™˜์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

media-container-query

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ๊ฐ€ ์—†์—ˆ์„ ์‹œ์ ˆ์—๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ Resize Observer ๊ธฐ์ˆ ์„ ํ†ตํ•ด ํŠน์ • ์š”์†Œ์˜ ํฌ๊ธฐ ๋ณ€ํ™”๋ฅผ ๊ด€์ฐฐํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ๋กœ ์Šคํƒ€์ผ๋ง์„ ํ•ด์ฃผ์–ด์•ผ ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด์ œ ๊ฐ„๋‹จํ•œ CSS ์ปจํ…Œ์ด๋„ˆ ๋ฌธ๋ฒ• ์ง€์ •์„ ํ†ตํ•ด ๋งค์šฐ ๊ฐ„ํŽธํ•˜๊ฒŒ ๋ณด๋‹ค ์„ธ๋ฐ€ํ•˜๊ณ  ์ •ํ™•ํ•œ ๋ฐ˜์‘ํ˜• ์ฟผ๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.


์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ์˜ ์žฅ์ 

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ ๊ธฐ๋Šฅ์ด ๋น›์„ ๋ฐœํ•˜๋Š” ์ˆœ๊ฐ„์€ ์•„๋ž˜์™€ ๊ฐ™์€ '์‹ฌํ”Œ ๋ชจ๋“œ' ๋‚˜ 'ํ™•์žฅ ๋ชจ๋“œ' ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋Š” ๋ฐ˜์‘ํ˜• ์‚ฌ์ด๋“œ๋ฐ”๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์šฐ์ธก ๋ณธ๋ฌธ ์˜์—ญ์— ๋Œ€ํ•œ ๋ฐ˜์‘ํ˜• ์Šคํƒ€์ผ๋ง์ด ํ•„์š”ํ•  ๋•Œ์ด๋‹ค.

media-container-querymedia-container-query

์˜ˆ๋ฅผ๋“ค์–ด ์ขŒ์ธก ์‚ฌ์ด๋“œ๋ฐ” ์˜์—ญ์„ ์ œ์™ธํ•œ ์šฐ์ธก ๋ณธ๋ฌธ ์˜์—ญ ์•ˆ์— ์žˆ๋Š” ์—ฌ๋Ÿฌ ์š”์†Œ๋“ค์„ ํ™ˆํŽ˜์ด์ง€์˜ ๊ฐ€๋กœํญ์— ๋”ฐ๋ผ ์š”์†Œ์— ๋ณ€ํ™”๋ฅผ ์ฃผ์–ด์•ผ ํ•œ๋‹ค๊ณ  ํ• ๋•Œ, ๊ธฐ์กด ๋ฐฉ์‹๋Œ€๋กœ ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ(@media)๋ฅผ ์“ด๋‹ค๋ฉด ์‚ฌ์ด๋“œ๋ฐ” ์˜์—ญ์„ ํฌํ•จํ•œ ์ „์ฒด ๋ธŒ๋ผ์šฐ์ € ๊ฐ€๋กœํญ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— '์‹ฌํ”Œ ๋ชจ๋“œ' ์ผ๋•Œ ์™€ 'ํ™•์žฅ ๋ชจ๋“œ' ์ผ๋•Œ๋ฅผ ๋ชจ๋‘ ๊ณ ๋ คํ•ด์•ผ ๋˜์–ด ๊ฐ™์€ ๋””์ž์ธ์„ ์ ์šฉํ•˜๋”๋ผ๋„ ๋ณธ๋ฌธ๊ณผ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•ด์•ผํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ๋‹ค.

๊ตณ์ด ๊ตฌํ˜„ํ•œ๋‹ค ๋ผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์ด๋“œ๋ฐ”๊ฐ€ '์‹ฌํ”Œ ๋ชจ๋“œ' ๋ƒ 'ํ™•์žฅ ๋ชจ๋“œ' ์— ๋”ฐ๋ผ ์‚ฌ์ด๋“œ๋ฐ”์˜ ๊ธธ์ด์— ๋”ฐ๋ผ ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ๋ฅผ ๋‘๋ฒˆ ๊ตฌํ˜„ํ•ด์•ผ ํ• ์ง€๋„ ๋ชจ๋ฅธ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ณธ๋ฌธ(main) ์˜์—ญ ๋ถ€๋ถ„์ด ์‚ฌ์ด๋“œ๋ฐ” ๊ธธ์ด์™€ ํ•จ๊ป˜ ๋ธŒ๋ผ์šฐ์ € ํญ์„ ๊ณ„์‚ฐํ•ด์•ผ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

main {
	width: 1100px;
}

/* ์‚ฌ์ด๋“œ๋ฐ” ํ™•์žฅ ๋ชจ๋“œ ์ƒํƒœ์ผ๋•Œ์˜ ๋ฐ˜์‘ํ˜• ์ฟผ๋ฆฌ */
@media screen and (max-width: 1400px) {
    html[data-sidebar='expand'] main {
        padding: 0 35px;
        width: 100%;
    } 
}

/* ์‚ฌ์ด๋“œ๋ฐ” ์‹ฌํ”Œ ๋ชจ๋“œ ์ƒํƒœ์ผ๋•Œ์˜ ๋ฐ˜์‘ํ˜• ์ฟผ๋ฆฌ */
@media screen and (max-width: 1200px) {
    html[data-sidebar='simple'] main {
        padding: 0 35px;
        width: 100%;
    }
}

๊ทธ๋Ÿฌ๋‚˜ ์œ„์˜ ๋ณธ๋ฌธ์˜ main ์˜์—ญ์„ ์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ๋กœ ์ง€์ •ํ•œ๋‹ค๋ฉด, ์ขŒ์ธก ์‚ฌ์ด๋“œ๋ฐ” ์ƒํƒœ๋ฅผ ๋”ฐ์ง€์ง€ ์•Š๊ณ  ์˜ค๋กœ์ง€ main ์˜์—ญ์˜ ๊ฐ€๋กœํญ์— ๋”ฐ๋ผ ๋ฐ˜์‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ข€๋” ์ง๊ด€์ ์ด๊ณ  ์œ ์ง€ ๋ณด์ˆ˜ ์ข‹๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

main {
    width: 1100px;
    container-name : main-container;
    container-type : inline-size;
}

/* ๋ณธ๋ฌธ ๋ฉ”์ธ ํŠน์ • ์˜์—ญ์— ๋”ฐ๋ฅธ ๋ฐ˜์‘ํ˜• ์ฟผ๋ฆฌ */
@container main-container (max-width: 992px) { 
    html main {
        padding: 0 35px;
        width: 100%;
    }
}

CSS Container Queries ์ •๋ฆฌ

 

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ ์‚ฌ์šฉ๋ฒ•

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ๋Š” ๋ธŒ๋ผ์šฐ์ € viewport ๊ธฐ์ค€์ด ์•„๋‹Œ, ํŠน์ • ์š”์†Œ์˜ ํฌ๊ธฐ์— ๋”ฐ๋ผ ๋ฐ˜์‘์ ์ธ ๋™์ž‘์„ ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ€์žฅ ๋จผ์ € ํ•ด์•ผ ํ•  ์ผ์€ ๋ฐ˜์‘ํ˜•์„ ์ ์šฉํ•  ์ปจํ…Œ์ด๋„ˆ ์š”์†Œ๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์•ผ ํŠน์ • ์š”์†Œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์น˜์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

1. ๋จผ์ € ๋ฐ˜์‘ํ˜•์œผ๋กœ ๋“ฑ๋กํ•  ์š”์†Œ๋ฅผ ์ปจํ…Œ์ด๋„ˆ๋กœ ๋“ฑ๋กํ•ด์ค€๋‹ค.

container-name ์„ ํ†ตํ•ด ์ฟผ๋ฆฌ ์ปจํ…Œ์ด๋„ˆ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•œ๋‹ค.

div {
  container-name: div-container; /* ์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ ์š”์†Œ ์ด๋ฆ„ */
}

 

2. ์ปจํ…Œ์ด๋„ˆ ์š”์†Œ์˜ ํƒ€์ž…์„ ์ง€์ •ํ•ด์ค€๋‹ค.

container-type ์—๋Š” size, inline-size, normal ์†์„ฑ๊ฐ’์ด ์กด์žฌํ•œ๋‹ค.

  • inline-size : ์ธ๋ผ์ธ ๋ ˆ๋ฒจ ๊ธฐ์ค€์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ ์šฉ. ์š”์†Œ์˜ width ๊ฐ’์— ๋”ฐ๋ผ ๋ฐ˜์‘ํ˜•์ด ๋™์ž‘๋œ๋‹ค.
  • size : ๋ธ”๋ก ๋ ˆ๋ฒจ ๊ธฐ์ค€์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ ์šฉ. width ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ height ๊ฐ’์— ๋”ฐ๋ผ ๋ฐ˜์‘ํ˜•์ด ๋™์ž‘ ๋œ๋‹ค.
  • normal : ํ•ด๋‹น ๊ฐ’์ด ๋ถ€์—ฌ๋œ ์š”์†Œ๋ฅผ container์—์„œ ์ œ์™ธ์‹œํ‚จ๋‹ค. ์ผ์ข…์˜ none ์˜๋ฏธ๋ผ๊ณ  ๋ณด๋ฉด ๋˜๊ฒ ๋‹ค.
div {
    container-name: div-container;
    container-type: inline-size; /* ์™ ๋งŒํ•œ ์ƒํ™ฉ์—์„  inline-size ๋กœ ์ด์šฉํ•œ๋‹ค๊ณ  ๋ณด๋ฉด ๋œ๋‹ค */
}
div {
    /* container-name / container-type */
    container : div-container / inline-size; /* ํ•œ์ค„๋กœ๋„ ๋‹จ์ถ• ํ‘œํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค */
}

 

3. @container ๋ฐ˜์‘ ์น˜์ˆ˜๋ฅผ ์ง€์ •ํ•ด์ค€๋‹ค

@media ์ฟผ๋ฆฌ๋ฅผ ๋“ฑ๋กํ–ˆ๋˜ ๊ฒƒ ์ฒ˜๋Ÿผ ๋˜‘๊ฐ™์ด @container ์ฟผ๋ฆฌ๋ฅผ ๋“ฑ๋กํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ์ด๋•Œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„์„ ์ง€์ •ํ•ด์ฃผ๋ฉด ํŠน์ • ์ปจํ…Œ์ด๋„ˆ ๋‚ด์—์„œ๋งŒ ๋ฐ˜์‘ํ•˜๊ณ , ์ด๋ฆ„์„ ์ง€์ • ์•ˆํ•ด์ฃผ๋ฉด ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ์— ๋Œ€ํ•ด ์ „์—ญ์œผ๋กœ ๋ฐ˜์‘ํ•˜๊ฒŒ ๋œ๋‹ค.

/* ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ ์š”์†Œ์— ๋ฐ˜์‘ */
@container (min-width: 700px) {
  div {
    font-size: 2em;
  }
}

/* ํŠน์ • container-name์˜ ์š”์†Œ์— ๋ฐ˜์‘ */
@container div-container (min-width: 700px) {
  div {
    font-size: 2em;
  }
}

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ ๊ธธ์ด ๋‹จ์œ„

viewport์˜ vw, vh ๋‹จ์œ„ ์ฒ˜๋Ÿผ container์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•˜๋Š” ์ƒ๋Œ€ ๊ธฐ์ค€์  ๋‹จ์œ„๊ฐ€ ์กด์žฌํ•œ๋‹ค. ์ด ๋‹จ์œ„๊ฐ’์„ ์ด์šฉํ•˜๋ฉด ์š”์†Œ์˜ ๊ตฌ์ฒด์ ์ธ ๊ธธ์ด ๊ฐ’์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ํ•„์š” ์—†์ด ๋‹ค๋ฅธ ์ปจํ…Œ์ด๋„ˆ์—์„œ ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • cqw : ์ฟผ๋ฆฌ ์ปจํ…Œ์ด๋„ˆ ๋„ˆ๋น„์˜ 1%
  • cqh : ์ฟผ๋ฆฌ ์ปจํ…Œ์ด๋„ˆ ๋†’์ด์˜ 1%
  • cqi : ์ฟผ๋ฆฌ ์ปจํ…Œ์ด๋„ˆ ์ธ๋ผ์ธ ํฌ๊ธฐ์˜ 1%
  • cqb : ์ฟผ๋ฆฌ ์ปจํ…Œ์ด๋„ˆ์˜ ๋ธ”๋ก ํฌ๊ธฐ์˜ 1%
  • cqmin : cqi ๋˜๋Š” cqb ์ค‘ ๋” ์ž‘์€ ๊ฐ’
  • cqmax : cqi ๋˜๋Š” cqb ์ค‘ ๋” ํฐ ๊ฐ’
/* ์ปจํ…Œ์ด๋„ˆ์˜ ์ธ๋ผ์ธ ํฌ๊ธฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ œ๋ชฉ์˜ ๊ธ€๊ผด ํฌ๊ธฐ๋ฅผ ์„ค์ • */
@container (min-width: 700px) {
  div {
    font-size: 1em + 2cqi;
  }
}

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ ๋ธŒ๋ผ์šฐ์ € ์ง€์› ๋ฒ”์œ„

IE๋ฅผ ์ œ์™ธํ•˜๊ณค ์™ ๋งŒํ•œ PC, Mobile ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฌธ์ œ์—†์ด ๋ชจ๋‘ ์ง€์›๋จ์„ ๋ณผ ์ˆ˜ ์žˆ์–ด ๋”์šฑ๋” ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ์ด์œ ๊ฐ€ ์—†๋‹ค. 

media-container-query

 

์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ ํด๋ฆฌํ•„

๋งŒ์ผ ๋งˆ์ด๋„ˆํ•œ ๊ตฌํ˜• ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๊ผญ ์ง€์›ํ•ด์•ผ๋งŒ ํ•œ๋‹ค๋ฉด, ํด๋ฆฌํ•„(polyfill) ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์œผ๋‹ˆ ์ด๊ฑธ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ์‚ฌ์šฉ๋ฒ•๋„ css์— ์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ ๋ฌธ๋ฒ•์„ ์“ฐ๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋กœ๋“œํ•ด ์Šคํฌ๋ฆฝํŠธ๋งŒ ์‹คํ–‰ํ•˜๋ฉด ์•Œ์•„์„œ ๋ธŒ๋ผ์šฐ์ €์˜ ์ปจํ…Œ์ด๋„ˆ ์ฟผ๋ฆฌ ์ง€์› ์œ ๋ฌด๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ํด๋ฆฌํ•„ ํ•ด์ค€๋‹ค.

 

A first look at container-query-polyfill, a polyfill for CSS Container Queries

Surma has been working on container-query-polyfill, a lightweight polyfill for CSS Container Queries. Let’s take a look at how it works and how it differs from cqfill … What Unlike cqfill —which was covered here before— this Polyfill for Container

www.bram.us

<script src="https://unpkg.com/container-query-polyfill/dist/container-query-polyfill.modern.js"></script>
<script>
    const supportsContainerQueries = "container" in document.documentElement.style;
    if (!supportsContainerQueries) {
      import("container-query-polyfill");
    }
</script>

# ์ฐธ๊ณ ์ž๋ฃŒ

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries 

https://web.dev/cq-stable/