컨테이너 스타일 쿼리에 대해 자세히 알아보기

소스 노드 : 1765194

나는 일부를 썼다. 컨테이너 스타일 쿼리에 대한 초기 생각 조금 전. 아직 초기 단계입니다. 그것들은 이미 CSS 포함 모듈 레벨 1 사양 (현재 Editor's Draft 상태) 하지만 아직 몇 가지 중요한 논의가 진행 중입니다.

기본 아이디어는 컨테이너를 정의한 다음 계산된 스타일을 기반으로 하위 항목에 조건부로 스타일을 적용할 수 있다는 것입니다.

@container ?  {
  /* conditional styles */
}

지금까지 본 가장 좋은 예는 다음과 같은 항목에서 이탤릭체를 제거하는 것입니다. , 콘텐츠가 이미 기울임꼴로 표시된 상황에서 사용되는 경우:

em, i, q {
  font-style: italic; /* default UA behavior */
}

/* When the container's font-style is italic, remove italics from these elements. */
@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

그것이 일반적인 생각입니다. 그러나 당신이 그것을 몰랐다면, 사양의 편집자 인 Miriam Suzanne은 지속적이고 철저한 일련의 컨테이너 스타일 쿼리에 대한 개인 메모 공개적으로 사용할 수 있습니다. 요 전날 업데이트되었고 스타일 쿼리의 미묘한 측면에 대해 머리를 감싸려고 시간을 보냈습니다. 비공식적인 내용이지만 눈에 띄는 몇 가지를 적어보자고 생각했습니다. 누가 알아? 어쩌면 우리가 결국 기대할 수 있는 것일 수도 있습니다!

모든 요소는 스타일 컨테이너입니다.

명시적으로 할당할 필요도 없습니다. container-name or container-type 모든 것이 기본적으로 스타일 컨테이너이기 때문에 스타일 컨테이너를 정의합니다.

위의 이탤릭체를 제거하는 예를 보셨습니까? 컨테이너를 식별하지 않습니다. 다음을 사용하여 쿼리로 바로 이동합니다. style() 기능. 그렇다면 어떤 컨테이너가 쿼리되고 있습니까? 그것은 될 것입니다 요소의 직접 부모 적용된 스타일을 받습니다. 그리고 그렇지 않다면 그것은 다음으로 가장 가까운 상대 컨테이너 그게 우선입니다.

나는 그것을 좋아한다. 쿼리가 일치하는 항목을 검색한 다음 일치하는 조건을 찾을 때까지 계속 버블링하는 것은 매우 CSS 스타일입니다.

내 작은 머리로는 스타일에 기반한 암시적 컨테이너를 사용할 수 있지만 다음과 같은 차원 쿼리를 처리할 때는 그렇지 않은 이유를 이해하기 어려웠습니다. sizeinline-size. Miriam은 다음과 같이 친절하게 설명합니다.

차원 쿼리에는 CSS가 필요합니다. 봉쇄 레이아웃 루프를 방지하기 위해 컨테이너의 크기, 레이아웃 및 스타일. 포함은 광범위하게 적용하기에는 침습적이므로 작성자가 어떤 요소가 컨테이너 크기인지(또는 아닌지)를 신중하게 제어하는 ​​것이 중요했습니다.

스타일 기반 쿼리에는 동일한 제한이 없습니다. 자손 스타일이 조상의 계산된 스타일에 영향을 미치도록 CSS에는 이미 방법이 없습니다. 따라서 봉쇄가 필요하지 않으며 요소를 하나의 요소로 설정할 때 침습적이거나 예기치 않은 부작용이 없습니다. 스타일 쿼리 컨테이너.

(강조 광산)

모든 것이 결과로 귀결됩니다. 모든 것이 즉시 사용할 수 있는 스타일 쿼리 컨테이너인 한 아무것도 없습니다.

  • 컨테이너가 발견되면 해당 컨테이너에 대해 조건이 해결됩니다.
  • 여러 컨테이너가 일치하는 경우: 가장 가까운 상대 컨테이너가 우선합니다.
  • 일치하는 항목이 없는 경우: unknown 반환되었습니다.

그건 똑같아 나머지 CSS와 같은 "용서" 정신.

컨테이너는 차원 및 스타일 쿼리를 모두 지원할 수 있습니다.

명시적인 코드 없이 스타일 쿼리를 정의하고 싶다고 가정해 보겠습니다. container-name:

@container style(font-style: italic) {
  em {
    font-style: normal;
  }
}

이것은 작동하기 때문에 모든 요소는 스타일 컨테이너입니다., 상관없이 container-type. 이것이 암시적으로 스타일을 쿼리하고 가장 가까운 일치 항목에 의존할 수 있게 해주는 것입니다. 스타일 컨테이너를 설정할 때 부작용이 없기 때문에 이것은 완전히 괜찮습니다.

우리는 명시적인 container-type 차원 쿼리의 경우 모든 요소가 스타일 쿼리이므로 스타일 쿼리의 경우 그다지 많지 않습니다. 이는 또한 이 컨테이너가 스타일이라는 것을 의미합니다. 차원 쿼리:

.card-container {
  container: card / inline-size; /* implictly a style query container as well */
}

쿼리에서 컨테이너 제외

컨테이너가 일치 프로세스에 참여하는 것을 원하지 않을 수도 있습니다. 설정할 수 있는 곳입니다. container-type: none 요소에.

.some-element {
  container-type: none;
}

명시적 스타일 쿼리 컨테이너는 쿼리 대상에 대한 더 많은 제어 기능을 제공합니다.

예를 들어 스타일 쿼리를 작성한다면 padding , 명시적으로 명명된 컨테이너 또는 가장 가까운 직계 부모로 작업하는지 여부에 관계없이 가장 일치하는 컨테이너를 결정할 수 있는 신뢰할 수 있는 방법이 없습니다. 그것은 ~ 때문에 padding 상속재산이 아닙니다.

따라서 이러한 경우에 우리는 다음을 사용해야 합니다. container-name 가져올 수 있는 컨테이너를 브라우저에 명시적으로 알립니다. 더 많은 조건과 일치하도록 컨테이너에 여러 명시적 이름을 지정할 수도 있습니다.

.card {
  container-name: card layout theme;
}

아, 그리고 container-name 선택적 및 재사용 가능한 컨테이너 이름! 이는 일치 항목을 검색할 때 브라우저가 선택을 하도록 돕는 데 있어서 훨씬 더 유연합니다.

.theme {
  container-name: theme;
}
.grid {
  container-name: layout;
}
.card {
  container-name: card layout theme;
}

하나의 컨테이너가 전달되는 경우에도 "대체"로 간주될 수 있는지 궁금합니다.

스타일 쿼리를 결합할 수 있습니다.

XNUMXD덴탈의 orand 연산자를 사용하면 wueries를 결합하여 건조 상태를 유지할 수 있습니다.

@container bubble style(--arrow-position: start start) or style(--arrow-position: end start) {
  .bubble::after {
    border-block-end-color: inherit;
    inset-block-end: 100%;
  }
}

/* is the same as... */
@container bubble style(--arrow-position: start start) {
  /* etc. */
}
@container bubble style(--arrow-position: end start) {
  /* etc. */
}

토글 스타일

컨테이너 스타일 쿼리와 정의하기 위해 수행되는 작업 toggle() 기능. 예를 들어 두 가지를 순환할 수 있습니다. font-style 값, 말 italicnormal:

em, i, q {
  font-style: italic;
}

@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

시원한. 그러나 CSS Toggles에 대한 제안은 toggle() 함수는 더 간단한 접근 방식입니다.

em, i, q {
  font-style: toggle(italic, normal);
}

그러나 이러한 종류의 바이너리 사용 사례를 넘어서는 것은 어디에 있습니까? toggle() 덜 적합합니다. 그러나 스타일 쿼리는 사용하기에 좋습니다. Miriam은 스타일 쿼리가 toggle():

/* When font-style is italic, apply background color. */
/* Toggles can only handle one property at a time. */
@container style(font-style: italic) {
  em, i, q {
    background: lightpink;
  }
}

/* When font-style is italic and --color-mode equals light */
/* Toggles can only evaluate one condition at a time */
@container style((font-style: italic) and (--color-mode: light)) {
  em, i, q {
    background: lightpink;
  }
}

/* Apply the same query condition to multiple properties */
/* Toggles have to set each one individually as separate toggles */
@container style(font-style: italic) {
  em, i, q {
    /* clipped gradient text */
    background: var(--feature-gradient);
    background-clip: text;
    box-decoration-break: clone;
    color: transparent;
    text-shadow: none;
  }
}

스타일 쿼리는 "Custom Property Toggle Hack"을 해결합니다.

스타일 쿼리는 "CSS 사용자 정의 속성 토글 트릭". 거기에서 빈 사용자 지정 속성(--foo: ;) 그리고 쉼표로 구분된 폴백 방법을 사용하여 사용자 지정 속성이 실제 값으로 설정될 때 속성을 켜거나 끕니다.

button {
  --is-raised: ; /* off by default */
  
  border: 1px solid var(--is-raised, rgb(0 0 0 / 0.1));
  box-shadow: var(
    --is-raised,
    0 1px hsl(0 0% 100% / 0.8) inset,
    0 0.1em 0.1em -0.1em rgb(0 0 0 / 0.2)
  );
  text-shadow: var(--is-raised, 0 -1px 1px rgb(0 0 0 / 0.3));
}

button:active {
  box-shadow: var(--is-raised, 0 1px 0.2em black inset);
}

#foo {
  --is-raised: initial; /* turned on, all fallbacks take effect. */
}

그것은 매우 멋지고 스타일 컨테이너 쿼리가 사소하게 만드는 많은 작업이기도 합니다.

스타일 쿼리 및 CSS 생성 콘텐츠

에서 제작한 생성 콘텐츠의 경우 content 의 재산 ::before::after 의사 요소에서 일치하는 컨테이너는 콘텐츠가 생성되는 요소입니다.

.bubble {
  --arrow-position: end end;
  container: bubble;
  border: medium solid green;
  position: relative;
}

.bubble::after {
  content: "";
  border: 1em solid transparent;
  position: absolute;
}

@container bubble style(--arrow-position: end end) {
  .bubble::after {
    border-block-start-color: inherit;
    inset-block-start: 100%;
    inset-inline-end: 1em;
  }
}

스타일 쿼리 및 웹 구성 요소

웹 구성 요소를 컨테이너로 정의하고 스타일별로 쿼리할 수 있습니다. 먼저, 우리는 구성 요소:


  
… …

그런 다음 우리는 :host 설정할 컨테이너로서의 의사 요소 container-namecontainer-type, 그리고 그것에 대한 몇 가지 높은 수준의 속성:

:host {
  container: media-host / inline-size;
  --media-location: before;
  --media-style: square;
  --theme: light;
}

내부의 요소 의 매개변수를 쿼리할 수 있습니다. 요소:

@container media-host style(--media-style: round) {
  [part='img'] {
    border-radius: 100%;
  }
}

무엇 향후 계획?

다시 말하지만, 여기에 적어둔 모든 내용은 Miriam의 메모를 기반으로 하며 해당 메모는 공식 사양을 대신할 수 없습니다. 그러나 그것들은 논의되고 있는 것과 미래에 어떤 일이 일어날 수 있는지에 대한 표시입니다. 저는 미리암이 우리가 최신 정보를 얻기 위해 팔로우할 수 있는 몇 가지 뛰어난 토론을 연결해 준 것에 감사드립니다.

타임 스탬프 :

더보기 CSS 트릭