1. 소개
이 섹션은 규범적이지 않습니다.
이 모듈은 2D 이미지를 표현하는 추가적인 방법을 도입합니다. 예를 들어 컬러 폴백이 있는 URL, 원뿔형 그라디언트, 또는 문서 내 다른 요소의 렌더링 결과 등입니다.
1.1. 값 정의
이 명세는 CSS 속성 정의 규약을 [CSS2]로부터 따르며, 값 정의 문법은 [CSS-VALUES-3]을 따릅니다. 이 명세에서 정의되지 않은 값 타입들은 CSS Values & Units [CSS-VALUES-3]에서 정의됩니다. 다른 CSS 모듈과의 결합으로 이러한 값 타입의 정의가 확장될 수 있습니다.
각 속성 정의에 명시된 속성별 값 이외에도, 이 명세에서 정의된 모든 속성은 CSS 전역 키워드를 속성 값으로 허용합니다. 가독성을 위해 별도로 반복 표기하지 않았습니다.
2. 2D 이미지 값: <image> 타입
<image> 값 타입은 2D 이미지를 나타냅니다. 이는 url 참조, image 표기, 또는 gradient 표기가 될 수 있습니다. 문법은 다음과 같습니다:
<image> = <url> | <image () > | <image-set () > | <cross-fade () > | <element () > | <gradient>
<image>는 다양한 CSS 속성에서 사용할 수 있습니다. 예를 들어 background-image, list-style-image, cursor 속성 [CSS2] (이 경우 속성 값에서 <url> 구성요소를 대체함) 등이 있습니다.
어떤 경우에는 이미지가 유효하지 않을 수 있습니다. 예를 들어 <url>이 올바르지 않은 이미지 포맷을 가리키거나 로드에 실패했을 때가 해당합니다. 유효하지 않은 이미지는 투명 단색 이미지로 렌더링되며 자연 치수를 가지지 않습니다. 하지만 유효하지 않은 이미지는 일부 상황에서 오류 처리 절차를 유발할 수 있습니다. 예를 들어 유효하지 않은 이미지가 list-style-image에 사용될 경우 none으로 처리되어 list-style-type이 대신 렌더링될 수 있습니다. [CSS2]
이미지가 로딩 중일 때는 로딩 중인 이미지입니다. 로딩 중인 이미지는 유효하지 않은 이미지가 아니지만 비슷한 동작을 가집니다: 투명 단색 이미지로 렌더링되며 자연 치수를 가지지 않습니다. 그리고 폴백 렌더링이 제공되는 상황에서는 폴백 렌더링을 유발할 수 있지만, 폴백 리소스의 로드를 유발해서는 안 됩니다. 또한 로딩 중인 이미지가 이미 로드된 이미지를 대체하는 경우 (예: 문서나 스타일시트가 변경되어서) UA가 해당 정보를 추적하고 있다면, 로딩 중인 이미지 대신 이미 로드된 이미지를 계속 렌더링할 수도 있습니다.
부분적으로만 로드된 이미지(즉, 자연 치수는 알려졌으나 이미지 데이터가 완전히 로드되지 않은 경우)는 로딩 중인 이미지로 처리하거나 일부 데이터만 렌더링된 로드된 이미지로 처리할 수 있습니다. 예를 들어 UA는 인터레이스 GIF의 첫 번째 패스 픽셀 데이터가 로드되는 즉시 렌더링할 수도 있고, 이미지 헤더(크기 정보 포함)가 파싱되는 즉시 렌더링을 시작할 수도 있으며, 아니면 전체 이미지가 로드될 때까지 기다릴 수도 있습니다.
계산된 <image> 값은 지정된 값에서 모든 <url>, <color>, <length>가 계산된 결과입니다.
2.1. 이미지 파일 포맷
UA는 <image> 값으로 참조될 때, <image>가 유효한 모든 속성에서 최소한 다음 이미지 파일 포맷을 지원해야 합니다:
- PNG, [PNG]에 명시됨
- SVG, [SVG11]에 명시됨, 보안 정적 모드 사용 ([SVG-INTEGRATION] 참고)
- UA가 애니메이션 <image>를 지원한다면, [SVG11]에 명시된 SVG, 보안 애니메이션 모드 사용 ([SVG-INTEGRATION] 참고)
UA는 다른 파일 포맷도 지원할 수 있습니다.
2.2. 이미지 참조: url() 표기법
참고: [css-images-3]와 변경 없음.
2.3. 외부 이미지 가져오기
스타일시트를 위한 외부 이미지 가져오기란, <url> url과 CSS 스타일 선언 declaration이 주어졌을 때, 스타일 리소스 가져오기를 url에 대해 실행하며, ruleOrDeclaration에는 declaration을, destination은 "image", CORS 모드는 "no-cors"로 지정하고, processResponse는 다음 단계로 진행합니다: response res와 null, 실패, 또는 바이트 스트림 byteStream이 주어질 때: byteStream이 바이트 스트림이라면, 해당 바이트 스트림으로부터 이미지를 로드합니다.
2.4. 해상도/타입 협상: image-set() 표기법
사용자 기기에 가장 적합한 이미지 해상도를 제공하는 것은 어려운 일일 수 있습니다. 이상적으로는 이미지는 사용 중인 기기의 해상도와 같아야 하나, 이 해상도는 사용자마다 다를 수 있습니다. 그러나 어떤 이미지를 전달할지 결정할 때 다른 요소들도 영향을 줄 수 있습니다; 예를 들어 사용자가 느린 모바일 네트워크를 사용 중이라면, 고해상도 이미지를 기다리기보다 저해상도 이미지를 받고 싶을 수 있습니다. image-set() 함수는 저자(author)가 이런 문제 대부분을 신경쓰지 않아도 되게 해주며, 단순히 복수 해상도의 이미지를 제공하고 UA가 상황에 맞게 가장 적합한 이미지를 선택하도록 합니다.
이 솔루션은 해상도가 파일 크기의 대리값이라는 가정에 기반하며, 그 결과 벡터 이미지의 다중 해상도 세트나 벡터와 래스터 이미지를 혼합하는 경우(예: 아이콘)에 적절히 대응하지 못합니다. 예를 들어 고해상도에는 벡터를, 저해상도에는 픽셀 최적화 비트맵을, 저대역폭에는(비록 해상도는 더 높지만) 파일 크기가 더 작으므로 다시 벡터를 사용할 수 있습니다.
image-set()의 문법은 다음과 같습니다:
<image-set () > =image-set ( <image-set-option>#) <image-set-option> =[ <image> | <string>] [ <resolution> ||type ( <string>) ] ?
HTML의 picture 기능과 맞추기 위해 "w"와 "h" 차원을 추가해야 합니다.
<string>은 image-set() 내부에서 <url>을 나타냅니다.
image-set() 함수는 자기 자신을 직접 또는 간접적으로(다른 <image> 타입의 인자로써) 중첩해서 사용할 수 없습니다.
<image-set-option> 각각은 image-set() 함수가 나타낼 수 있는 가능한 이미지를 정의하며, 세 부분으로 구성됩니다:
-
이미지 참조(필수). 이는 URL일 수도 있고, CSS 생성 이미지일 수도 있습니다. 예를 들어 linear-gradient() 등이 있습니다.
-
<resolution> (선택적). UA가 어떤 <image-set-option>을 선택할지 결정하는 데 사용됩니다. 이미지 참조가 래스터 이미지일 경우, 이미지는 고유 해상도가 지정되며, 정보의 다른 출처에서 고유 해상도를 제공하더라도 이를 덮어씁니다.
명시하지 않을 경우, 어떤 <image-set-option>을 선택할지 결정할 때 1x로 동작합니다. 또한 이미지의 고유 해상도의 기본값도 1x이지만, 만약 다른 데이터 출처에서 고유 해상도를 제공한다면 반드시 그 해상도를 따라야 합니다.
-
type( <string> ) 함수(선택적)는, <string>에 이미지의 MIME 타입을 명시합니다.
<string>이 유효한 MIME 타입 문자열로 파싱될 때, 유효하지 않거나, 유효하지만 지원되는 이미지 포맷을 지정하지 않을 경우, <image-set-option>은 유효한 옵션을 정의하지 않습니다. (이것이 image-set() 함수의 유효성에는 영향을 주지 않습니다.)
이 값은 이미지 자체에는 영향을 주지 않습니다;
과 같은 <image-set-option>은 유효하며, 선택될 경우 PNG 이미지를 표시하지만, 선언은 JPEG임에도 PNG가 실제 표시됩니다.url ( "picture.png" ) 1 x type ( "image/jpeg" ) 명시하지 않을 경우, <image-set-option>에 아무런 영향도 주지 않습니다.
테스트
- image-set-all-options-invalid.html (실시간 테스트) (소스)
- image-set-calc-x-rendering-2.html (실시간 테스트) (소스)
- image-set-calc-x-rendering.html (실시간 테스트) (소스)
- image-set-computed.sub.html (실시간 테스트) (소스)
- image-set-conic-gradient-rendering.html (실시간 테스트) (소스)
- image-set-content-rendering.html (실시간 테스트) (소스)
- image-set-dpcm-rendering.html (실시간 테스트) (소스)
- image-set-dpi-rendering-2.html (실시간 테스트) (소스)
- image-set-dpi-rendering.html (실시간 테스트) (소스)
- image-set-dppx-rendering.html (실시간 테스트) (소스)
- image-set-empty-url-rendering.html (실시간 테스트) (소스)
- image-set-first-match-rendering.html (실시간 테스트) (소스)
- image-set-linear-gradient-rendering.html (실시간 테스트) (소스)
- image-set-negative-resolution-rendering-2.html (실시간 테스트) (소스)
- image-set-negative-resolution-rendering-3.html (실시간 테스트) (소스)
- image-set-negative-resolution-rendering.html (실시간 테스트) (소스)
- image-set-no-res-rendering-2.html (실시간 테스트) (소스)
- image-set-no-res-rendering.html (실시간 테스트) (소스)
- image-set-no-url-rendering.html (실시간 테스트) (소스)
- image-set-parsing.html (실시간 테스트) (소스)
- image-set-radial-gradient-rendering.html (실시간 테스트) (소스)
- image-set-rendering-2.html (실시간 테스트) (소스)
- image-set-rendering.html (실시간 테스트) (소스)
- image-set-repeating-conic-gradient-rendering.html (실시간 테스트) (소스)
- image-set-repeating-linear-gradient-rendering.html (실시간 테스트) (소스)
- image-set-repeating-radial-gradient-rendering.html (실시간 테스트) (소스)
- image-set-resolution-001.html (실시간 테스트) (소스)
- image-set-resolution-002.html (실시간 테스트) (소스)
- image-set-resolution-003.html (실시간 테스트) (소스)
- image-set-type-first-match-rendering.html (실시간 테스트) (소스)
- image-set-type-rendering-2.html (실시간 테스트) (소스)
- image-set-type-rendering-3.html (실시간 테스트) (소스)
- image-set-type-rendering.html (실시간 테스트) (소스)
- image-set-type-skip-unsupported-rendering.html (실시간 테스트) (소스)
- image-set-type-unsupported-rendering-2.html (실시간 테스트) (소스)
- image-set-type-unsupported-rendering.html (실시간 테스트) (소스)
- image-set-unordered-res-rendering.html (실시간 테스트) (소스)
- image-set-zero-resolution-rendering-2.html (실시간 테스트) (소스)
- image-set-zero-resolution-rendering.html (실시간 테스트) (소스)
image-set() 함수는 하나 이상의 <image-set-option> 목록을 포함하며, 이 중에서 오직 하나만 선택하여 어떤 이미지를 나타낼지 결정해야 합니다:
-
먼저, <image-set-option> 중 type() 값에 알 수 없거나 지원되지 않는 MIME 타입이 지정된 항목을 목록에서 제거합니다.
-
그 다음, <image-set-option> 중 앞에 나온 항목과 동일한 <resolution>을 가진 항목을 목록에서 제거합니다.
-
이 시점에 <image-set-option>이 남아있지 않다면, 해당 함수는 유효하지 않은 이미지를 나타냅니다.
-
마지막으로, 남아있는 <image-set-option> 중에서 UA는 상황에 맞게 적절하다고 판단되는 기준(예: 디스플레이 해상도, 네트워크 속도 등)에 따라 어느 이미지를 로드할지 선택합니다.
-
이후 image-set() 함수는 선택된 <image>를 대표하게 되며, 해당 <image-set-option>의 이미지를 사용합니다.
UA는 페이지가 표시되는 동안 기준이 충분히 크게 변화한다고 판단되는 경우, 특정 <image-set-option>을 사용할지 여부를 변경할 수 있습니다. 이때 image-set()에 대해 동적으로 선택이 바뀔 수 있습니다.
background-image : image-set ( "foo.png" 1 x , "foo-2x.png" 2 x , "foo-print.png" 600 dpi );
background-image : image-set ( "foo.avif" type ( "image/avif" ), "foo.jpg" type ( "image/jpeg" ) );
AVIF 이미지는 먼저 제공되고, 두 이미지 모두 해상도가 동일(지정되지 않았으므로 기본 1x)하기 때문에 JPEG 이미지는 두 번째로 오더라도 AVIF 이미지를 지원하는 UA에서는 자동으로 제외됩니다.
하지만 구형 UA에서는
AVIF 이미지가 무시되며
(
파일을 지원하지 않음을 UA가 인지하므로),
JPEG가 대신 선택됩니다.
예를 들어, 이 코드 조각에서는 미묘한 디테일이 있는 고해상도 이미지는 이를 제대로 표현할 수 있는 화면에서 사용하고, 저해상도 환경에서는 일반적인 CSS linear-gradient()가 대신 사용됩니다:
background-image : image-set ( linear-gradient ( cornflowerblue, white) 1 x , url ( "detailed-gradient.png" ) 3 x );
2.5. 이미지 폴백 및 주석: image() 표기법
image() 함수는 작성자가 다음을 할 수 있도록 해줍니다:
-
미디어 프래그먼트를 사용하여 이미지의 일부만 잘라내기
-
단색을 이미지로 사용하기
-
지정한 url의 이미지를 다운로드하거나 디코딩할 수 없는 경우 단색 이미지로 폴백하기
-
이미지 메타데이터에 지정된 이미지 방향을 자동으로 존중하기
image() 표기법은 다음과 같이 정의됩니다:
image () =image ( <image-tags>?[ <image-src>?, <color>?] !) <image-tags> =[ ltr | rtl] <image-src> =[ <url> | <string>]
<string>이 image()에서 사용될 경우 <url>을 나타냅니다. CSS에서의 URL과 마찬가지로, 상대 URL은 절대 URL로 변환됩니다 (Values & Units [CSS-VALUES-3]에 설명됨) 지정된 image() 값이 계산될 때.
이미지에 EXIF 등 메타데이터에 방향 정보가 있다면, UA는 해당 메타데이터에 따라 이미지를 올바른 방향으로 회전 또는 반전시켜야 합니다.
2.5.1. 이미지 폴백
image()에서 URL과 <color>가 둘 다 지정된 경우, URL이 유효하지 않은 이미지이거나 로딩 중인 이미지일 때마다, image() 함수는 URL이 전혀 지정되지 않은 것처럼 렌더링됩니다; § 2.5.3 단색 이미지에 지정된 대로 단색 이미지를 생성합니다.
URL만 지정되고 (<color>는 없는 경우) 해당 URL이 유효하지 않은 이미지 또는 로딩 중인 이미지라면, image() 함수도 동일하게 처리합니다.
테스트
body{ color : black; background : white; } p.special{ color : white; background : url ( "dark.png" ) black; }
이미지가 로드되지 않아도 배경색이 남아 있으므로 흰색 텍스트가 읽기 쉽습니다. 그러나 이미지에 일부 투명도가 있으면 그 뒤에 검정색이 보이게 되는데, 이는 대부분의 경우 원하지 않는 결과입니다. image() 함수가 이 문제를 해결합니다:
body{ color : black; background : white; } p.special{ color : white; background : image ( "dark.png" , black); }
이제 이미지를 정상적으로 불러오면 검정색이 전혀 보이지 않지만, 이미지를 불러오지 못하면 검정색이 나타나 흰 배경에 흰 글씨가 보이지 않는 상황을 막아줍니다.
2.5.2. 이미지 조각
image()에 지정된 URL이 리소스의 일부를 나타내는 경우 (예: 미디어 프래그먼트 식별자 사용) 해당 부분만 잘라내어 독립된 이미지로 사용됩니다.
background-image : image ( 'sprites.svg#xywh=40,0,20,20' )
...이 경우 해당 요소의 배경은 (40px, 0px)부터 시작하여 너비와 높이가 20px인 이미지 영역이 되어, 1/4만 채워진 원 하나만 표시됩니다.
작성자가 CSS의 전방 호환 파싱 규칙을 활용해 이미지 슬라이스의 폴백을 제공할 수 있도록,
image() 표기법을
지원하는 구현체는 xywh=#
형식의 미디어 프래그먼트 식별자를
image()를 통해 지정된 이미지에 대해 반드시 지원해야 합니다. [MEDIA-FRAGS]
image() 표기법은 미디어 프래그먼트 지원을 UA에 요구하므로, 작성자는 CSS의 전방 호환 파싱 규칙을 활용해 이미지 프래그먼트 URL 사용 시 폴백을 제공할 수 있습니다:
background-image : url ( 'swirl.png' ); /* 구형 UA */ background-image:image ( 'sprites.png#xywh=10,30,60,20' ); /* 최신 UA */
URL이 구현체가 이해하지 못하거나 해당 이미지 타입에 대해 유효하지 않다고 간주하는 프래그먼트 식별자 문법을 사용할 경우, 해당 URL은 유효하지 않은 이미지로 처리해야 합니다.
참고: 이 오류 처리는 image()에만 한정되며, 레거시 호환성을 위해 URL 정의에는 포함되지 않습니다.
2.5.3. 단색 이미지
image() 함수에 <color>만 (URL 없이) 지정된 경우, 지정한 색상의 단색 이미지를 나타내며 자연 치수가 없습니다.
background-image : image ( rgba ( 0 , 0 , 255 , .5 )), url ( "bg-image.png" );
background-color는 항상 모든 배경 이미지 아래에 단색이 위치하기 때문에, 이 용도로는 사용할 수 없습니다.
2.5.4. 양방향(Bidi) 민감 이미지
어떤 <image-src>s
를 나열하기 전에,
작성자는 이미지의 방향성을 지정할 수 있습니다.
이는 HTML 요소에 dir
속성을 추가하는 것과 유사합니다.
방향성 이미지를 반대 direction을 가진 요소 또는 그
내부에서 사용할 경우,
이미지는 인라인 방향으로 반전되어야 하며
(인라인 방향이 X축이라면
등으로
변환한 것처럼).
참고: 이 선언이 없으면, 이미지는 기본적으로 방향성이 없으며 따라서 주변 요소의 방향성을 신경 쓰지 않습니다.
< ul style = "list-style-image: image(ltr 'arrow.png');" > < li dir = 'ltr' > My bullet is on the left!</ li > < li dir = 'rtl' > MY BULLET IS ON THE RIGHT!</ li > </ ul >
이 코드는 다음과 같이 렌더링되어야 합니다:
⇒ My bullet is on the left! !THGIR EHT NO SI TELLUB YM ⇐
LTR 목록 항목에서는 이미지를 그대로 사용하고, RTL 항목에서는 인라인 방향으로 반전되어 여전히 콘텐츠 쪽을 가리키게 됩니다.
2.6. 이미지 결합: cross-fade() 표기법
이미지 간 전환 시, CSS는 시작 이미지와 끝 이미지를 조합한 중간 이미지를 명시적으로 참조할 방법이 필요합니다. 이는 cross-fade() 함수를 통해 이루어지며, 결합할 두 이미지를 지정하고 전환 진행 상황을 나타냅니다.
참고: 작성자는 cross-fade() 함수를 사용해 이미지에 단색 틴트를 입히거나, 이미지와 방사형 그라디언트를 결합해 특정 영역을 강조하는 등 여러 단순 이미지 조작도 할 수 있습니다.
cross-fade()의 문법은 다음과 같이 정의됩니다:
cross-fade () =cross-fade ( <cf-image>#) <cf-image> =[ <image> | <color>] && <percentage[ 0 , 100 ] >?
이 함수는 하나 이상의 이미지를 결합해 생성된 이미지를 나타냅니다.
<percentage>는 각 이미지가 다른 이미지와 혼합될 때 얼마만큼 유지되는지를 나타냅니다. <percentage>는 0%에서 100% 사이여야 하며; 다른 값은 유효하지 않습니다.
퍼센트가 생략된 경우, 지정된 모든 퍼센트를 합산해서 100%에서 빼고, 결과가 0%보다 작으면 0%로 바꾼 뒤, 생략된 이미지 개수로 똑같이 나누어 계산값 단계에서 할당합니다.
반대로 합이 100% 미만이면, 사이즈/페인팅 세부 처리에서 남은 값을 transparent 인자가 추가된 것처럼 동작하며, 해당 인자의 퍼센트는 남은 값이 됩니다.
<color>가 제공되면, 이는 "자동" 치수를 가진 단색 이미지를 나타냅니다 (결과 이미지 크기 결정에는 참여하지 않음; 아래의 크기 결정 세부사항 참고).
테스트
- cross-fade-basic.html (실시간 테스트) (소스)
- cross-fade-computed-value.html (실시간 테스트) (소스)
- cross-fade-legacy-crash.html (실시간 테스트) (소스)
- cross-fade-legacy-2-crash.html (실시간 테스트) (소스)
- cross-fade-natural-size.html (실시간 테스트) (소스)
- cross-fade-premultiplied-alpha.html (실시간 테스트) (소스)
- cross-fade-target-alpha.html (실시간 테스트) (소스)
2.6.1. cross-fade() 크기 지정
cross-fade()로 표현되는 이미지의 치수는 함수에 전달된 <image> 인자의 치수를 가중 평균한 값입니다; <color> 인자는 영향을 주지 않습니다. 계산 방법은 다음과 같습니다:
-
함수 인자에서 혼합 비율 정규화를 수행하고, args와 leftover를 결과로 받습니다.
-
leftover가 100%라면, 자연 치수가 없는 것으로 반환합니다.
-
images를 빈 리스트로 만듭니다.
-
함수 인자의 각 <cf-image> argument에 대해:
-
item을 너비, 높이, 비율로 구성된 튜플로 만듭니다.
-
오브젝트 크기 협상 알고리즘을 <image>에 대해 실행하고, item의 너비와 높이를 결과 구체적 오브젝트 크기의 값으로 설정합니다.
-
item의 비율을 argument의 비율로 설정합니다.
-
images가 비어있으면, 자연 치수 없음으로 반환합니다.
-
images의 각 항목의 너비와 높이를 해당 비율로 가중 평균하여 자연 너비와 자연 높이를 반환합니다.
참고: 비율 합이 100% 미만일 수 있으므로 단순 가중 평균 시에는 먼저 정규화가 필요할 수 있습니다.
2.6.2. cross-fade() 그리기
cross-fade()로 표현되는 이미지는 함수 인자들의 가중 평균값으로 계산됩니다:
-
함수 인자에서 혼합 비율 정규화를 수행하고, args와 leftover를 결과로 받습니다.
-
images를 빈 리스트로 만듭니다.
-
size를 튜플(너비, 높이)로 초기화하며, 구체적 오브젝트 크기를 (cross-fade()의 자연 치수 사용)로 구합니다.
-
cross-fade()의 각 argument에 대해:
-
leftover가 0%보다 크면, images에 튜플을 추가합니다(투명 검정색 단색 이미지, size 크기, 비율은 leftover).
-
final image는 size의 크기를 가지며, 각 픽셀은 각 item 이미지의 해당 픽셀을 item의 비율에 따라 가중 선형 평균한 값입니다. (색상 채널과 알파 채널 모두 평균합니다.) 이 계산에서는 각 픽셀 색상이 프리멀티플라이드 sRGB여야 합니다.
위 연산의 세부 내용
이는 소스 이미지에 대한 N-way Porter-Duff
dissolve
연산을 적용하는 것입니다. Wikipedia에 따르면dissolve
는 확률적(stochastic) 연산이며, 결과 픽셀은 소스 이미지의 해당 픽셀들에서 비율에 따라 무작위로 선택되지만, 픽셀이 무한히 작아질수록 프리멀티플라이드 색상 공간에서 색상 평균을 하는 것과 같아집니다.따라서 `cross-fade(white 50%, transparent 50%)`는 부분 투명 흰색 단색 이미지를 만듭니다. (불투명 흰색과 투명 검정색을 프리멀티플라이드가 아닌 공간에서 평균하면 회색이 나오지만, 여기서는 다름)
프리멀티플라이드 변환에서 약간의 정밀도 손실이 발생하며, 그래픽 라이브러리가 이를 네이티브로 지원하지 않을 수도 있지만, 요구 효과를 달성하는 한 어떤 방법이든 사용할 수 있습니다.
예를 들어 각 픽셀의 알파에 따라 비율을 재조정해 비프리멀티플라이드 공간에서 색상 채널만 평균할 수도 있습니다. 예를 들어 cross-fade(rgb(255 0 0 / 1) 40%, rgb(0 255 0 / .5) 20%, rgb(0 0 255 / 0) 40%)을 렌더링할 때, 알파 1 / .5 / 0을 기준으로 비율을 재조정하면 40% / 10% / 0%(정규화하면 80% / 20% / 0%)가 되고, 이 상태에서 색상 채널 원본값 평균을 하면 rgb(204 51 0 / .5) 이미지가 나옵니다. (알파 채널 평균은 원래 비율을 그대로 사용함에 주의)
-
final image를 반환합니다.
2.6.3. 복잡한 cross-fade() 단순화
WG 결의에 따라, 이미지의 "동등성" 개념을 정의하고, 계산값 단계에서 "같은" 이미지를 합쳐 비율을 합산합니다.
WG 결의에 따라, 계산값 단계에서 직접 중첩된 cross-fade()를 단순화하며, 퍼센트를 분배하고 평탄화(플래튼)합니다; cross-fade(A 10%, cross-fade(B 30%, C 70%) 90%)는 cross-fade(A 10%, B 27%, C 63%)로 변환됩니다.
2.7. 요소를 이미지로 사용하기: element() 표기법
element() 함수는 작성자가 문서 내 요소를 이미지로 사용할 수 있게 해줍니다. 참조된 요소의 모습이 바뀌면, 이미지도 함께 변경됩니다. 예를 들어, 슬라이드쇼에서 다음/이전 슬라이드의 실시간 미리보기를 만들거나, 캔버스 요소를 참조하여 멋진 생성형 그라디언트나 애니메이션 배경을 만들 때 사용할 수 있습니다.
참고: element() 함수는 참조된 요소의 외관만을 복제하며, 실제 내용 및 구조는 복제하지 않습니다. 작성자는 이 기능을 장식용(데코레이션) 목적으로만 사용해야 하며, 의미 있는 내용을 페이지 전체에 반복하려고 element()를 사용해서는 안 됩니다. 대신, 해당 요소를 문서에 여러 번 삽입하면 됩니다.
element()의 문법은 다음과 같습니다:
element () =element ( <id-selector>)
<id-selector>는 ID 선택자입니다 [SELECT].
외부 문서의 요소(예: SVG paint server)를 참조할 필요가 있을까요? 아니면 이를 위해 url()만으로 충분할까요?
이 이름은 GCPM의 유사한 함수와 충돌합니다. 이 부분은 해결이 필요합니다.
요소의 "반사(reflection)"를, 해당 요소의 background-image나 가상 요소에서 할 수 있기를 원합니다. 순환 감지(cycle-detection)를 유발하지 않도록 특별히 다뤄야 합니다.
overflow:paged가 있을 때, 뷰 내의 단일 페이지를 어떻게 지정할 수 있을까요?
element() 함수는 인자로 전달된 값과 일치하는 요소를 참조합니다. ID는 먼저 elementSources 맵에서 검색되며, 해당 섹션에 설명된 대로 동작합니다. 찾을 수 없는 경우, 문서에서 검색합니다. 여러 요소가 일치할 경우, 첫 번째 요소를 참조합니다.
element() 함수로 표현되는 이미지는, 참조된 요소가 문서에서 시각적으로 렌더링되는지에 따라 달라집니다:
- 렌더링되는 요소이고, 대체 요소의 하위가 아니며, 스태킹 컨텍스트를 생성하는 경우
-
함수는 참조된 요소의 데코레이션
바운딩 박스와 동일한 자연 크기를 가진 이미지를 나타냅니다:
- CSS 렌더링 모델로 렌더링되는 요소의 경우, 데코레이션 바운딩 박스란 해당 principal box의 모든 fragment의 border image area를 포함하는 최소한의 축정렬 사각형입니다.
- SVG 렌더링 모델로 렌더링되는 요소의 경우, SVG에서 정의한 대로 데코레이션 바운딩 박스가 결정됩니다.
참고: 이미지는 기본적으로 경계 밖을 클리핑하므로, 데코레이션 바운딩 박스를 벗어나는 그림자와 같은 장식은 잘릴 수 있습니다.
이미지는 참조된 요소와 그 하위 요소를 (문서에서와 동일한 크기로) 무한 투명 캔버스 위에 렌더링하여, 데코레이션 바운딩 박스의 경계가 이미지 경계와 딱 맞도록 배치됩니다.
효율적인 구현을 위해 스태킹 컨텍스트가 어느 정도 필요해 보입니다. 전체 스태킹 컨텍스트가 필요한가요, 아니면 의사 스태킹 컨텍스트로도 충분한가요? 평소에 스태킹 컨텍스트여야 하는지, 아니면 element()로 렌더링할 때만 스태킹 컨텍스트로 처리해도 괜찮을까요?
참조된 요소나 조상에 transform이 적용되어 있으면, 이미지를 렌더링할 때 해당 transform은 무시해야 합니다. [CSS3-TRANSFORMS]
참조된 요소가 여러 페이지에 걸쳐 분할되어 있으면, 페이지 컨텐트 영역이 페이지 나누기 방향으로 이어진 것처럼 요소를 표시하며, 각 페이지의 경계는 초기 포함 블록의 시작 경계와 정렬합니다. 줄바꿈 또는 컬럼 분할로 분할된 경우는 해당 데코레이션 바운딩 박스로만 렌더링합니다.
구현체는 참조된 요소를 위해 이미 생성된 비트맵 데이터를 재사용하거나, 이미지 크기에 맞춰 품질을 극대화하려고 요소를 다시 그릴 수 있습니다 (예: 참조 요소가 SVG fragment임을 감지한 경우). 후자의 경우, 이미지 내 참조 요소의 레이아웃은 재생성 과정에서 변하지 않아야 합니다. 즉, 이미지는 레스터화 품질을 뺀 나머지는 참조 요소와 시각적으로 동일해야 합니다.
조금 우스꽝스럽긴 하지만,
p
요소를 문서의 다른 곳에서 배경으로 다시 사용할 수 있습니다:< style > # src { color : white ; background : lime ; width : 300 px ; height : 40 px ; position : relative ; } # dst { color : black ; background : element ( #src ); padding : 20 px ; margin : 20 px 0 ; } </ style > < p id = 'src' > 저는 평범한 요소입니다!</ p > < p id = 'dst' > 저는 앞의 요소를 배경으로 사용합니다!</ p > - 렌더링되지 않는 요소이지만 페인트 소스를 제공하는 경우
-
함수는 자연 치수와 페인트 소스의 외관을 가진 이미지를 나타냅니다.
호스트 언어는 페인트 소스의 크기와 외관을 정의합니다.
예를 들어 element() 함수는 HTML 문서의 SVG
<pattern>
요소를 참조할 수 있습니다:<!DOCTYPE html> < svg > < defs > < pattern id = 'pattern1' > < path d = '...' > </ pattern > </ defs > </ svg > < p style = "background: element(#pattern1)" > 패턴을 배경으로 사용합니다! 패턴이 변경되거나 애니메이션되면, 제 배경도 자동으로 업데이트됩니다!</ p > HTML은 또한
canvas
,img
,video
등이 페인트 소스를 제공한다고 정의합니다. 즉, CSS에서 예를 들어 문서에 표시되지 않는 캔버스를 참조해 사용할 수 있습니다:<!DOCTYPE html> < script > var canvas= document. querySelector( '#animated-bullet' ); canvas. width= 20 ; canvas. height= 20 ; drawAnimation( canvas); </ script > < canvas id = 'animated-bullet' style = 'display:none' ></ canvas > < ul style = "list-style-image: element(#animated-bullet);" > < li > 저는 캔버스를 불릿으로 사용합니다!</ li > < li > 저도요!</ li > < li > Javascript로 캔버스가 시간이 흐르며 변경되면, 우리 모두 그 이미지를 불릿으로 업데이트합니다!</ li > </ ul > - 그 외의 경우
-
함수는 유효하지 않은 이미지를 나타냅니다.
예를 들어, 아래의 모든 element() 사용은 투명 배경이 됩니다:
<!DOCTYPE html> < p id = 'one' style = "display:none; position: relative;" > one</ p > < iframe src = "http://example.com" > < p id = 'two' style = "position: relative;" > 저는 폴백 콘텐츠입니다!</ p > </ iframe > < ul > < li style = "background: element(#one);" > display:none인 요소는 렌더링되지 않으며, P 요소는 페인트 소스를 제공하지 않습니다.</ li > < li style = "background: element(#two);" > IFRAME과 같은 대체 요소의 자손은 element()로 사용할 수 없습니다.</ li > < li style = "background: element(#three);" > "three"라는 id를 가진 요소가 없으므로, 이것도 투명 이미지로 렌더링됩니다.</ li > </ ul >
요소는 연관된 박스가 없으면 렌더링되지 않는다고 간주합니다.
예를 들어 요소나 조상이 display:none일 때 이런 일이 발생할 수 있습니다.
호스트 언어는 요소가 렌더링되지 않은 것으로 간주되는 추가적인 방식을 정의할 수 있습니다;
예를 들어 SVG에서 <defs>
요소의 모든 자손은 렌더링되지 않은 것으로 간주됩니다.
element() 함수는 여러 용도로 사용할 수 있습니다. 예를 들어 슬라이드쇼의 이전 또는 다음 슬라이드 미리보기를 표시하는 데 사용할 수 있습니다:
<!DOCTYPE html> < script > function navigateSlides() { var currentSlide= ...; document. querySelector( '#prev-slide' ). id= '' ; document. querySelector( '#next-slide' ). id= '' ; currentSlide. previousElementSibling. id= 'prev-slide' ; currentSlide. nextElementSibling. id= 'next-slide' ; } </ script > < style > . slide { /* element()를 사용하려면 스태킹 컨텍스트여야 합니다. */ position : relative ; } # prev-preview , # next-preview { position : fixed ; ...} # prev-preview { background : element ( #prev -slide ); } # next-preview { background : element ( #next -slide ); } </ style > < a id = 'prev-preview' > 이전 슬라이드</ a > < a id = 'next-preview' > 다음 슬라이드</ a > < section class = 'slide' > ...</ section > < section class = 'slide current-slide' > ...</ section > ...
이 예제에서는 navigateSlides
함수가 다음/이전 슬라이드의 id를 업데이트하며,
이는 슬라이드 옆에 작은 플로팅 박스로 표시됩니다.
element() 함수는 슬라이드를 상호작용할 수 있게 만들지 않으므로(그저 이미지일 뿐),
미리보기 박스에 click
핸들러를 달아 페이지를 탐색할 수도 있습니다.
2.7.1. 페인트 소스(Paint Sources)
호스트 언어는 일부 요소가 페인트 소스를 제공한다고 정의할 수 있습니다. 페인트 소스는 고유한 외관을 가지며, 레이아웃이나 렌더링을 하지 않아도 구체적 오브젝트 크기를 얻을 수 있으므로, 렌더링되지 않아도 이미지로 사용할 수 있습니다.
HTML에서는
img
,
video
,
canvas
요소가 페인트 소스를 제공합니다.
SVG에서는 페인트 서버를 제공하는 모든 요소가 페인트 소스가 됩니다. 참고: SVG1.1에서는
<linearGradient>
, <radialGradient>
,
<pattern>
요소가 페인트 소스를 제공합니다. 이들은 명세에 설명된 대로 그려지며,
좌표계는 다음과 같이 정의됩니다:
- objectBoundingBox
- 좌표계의 원점은 그려지는 구체적 오브젝트 크기의 사각형 왼쪽 위 모서리에 있으며, 너비와 높이가 구체적 오브젝트 크기와 같습니다. 한 사용자 좌표는 구체적 오브젝트 크기의 너비와 높이와 같습니다.
- userSpaceOnUse
- 좌표계의 원점은 그려지는 구체적 오브젝트 크기의 사각형 왼쪽 위 모서리에 있으며, 너비와 높이가 구체적 오브젝트 크기와 같습니다. 사용자 좌표의 단위는 CSS px 단위와 같습니다.
참고: 이 모듈의 향후 버전에서는 외부 문서에 있는 페인트 소스, 또는 스크립트로만 생성되고 문서에 삽입되지 않는 페인트 소스를 참조하는 방법이 정의될 예정입니다.
2.7.2. 문서 외부 소스 사용: ElementSources
인터페이스
element()
함수는 일반적으로 문서 내 요소를 선택하지만,
페인트 소스를 제공하는 요소는 반드시 문서 내에 있을
필요는 없습니다.
예를 들어 HTML
canvas
요소는 스크립트로만 생성, 관리, 그리기가 가능하며,
문서에 직접 삽입할 필요가 없습니다.
필요한 것은 해당 요소를 참조할 방법뿐인데, ID 선택자는 문서 외부 요소를 선택할 수 없습니다. elementSources Map 객체가 이 역할을 합니다.
partial namespace CSS { [SameObject ]readonly attribute any ; };
elementSources
elementSources 맵의 문자열 키와 페인트 소스를 제공하는 객체 값을 가진 엔트리는 element() 함수에서 사용할 수 있게 됩니다.
element()가
<id-selector>를 사용하는 경우,
ID 값(선행 #
없이)을 먼저 elementSources 맵에서 찾습니다:
- 발견되었고, 연결된 객체가 페인트 소스를 제공하면, element() 함수는 해당 페인트 소스를 나타냅니다.
- 발견되었지만, 연결된 객체가 페인트 소스를 제공하지 않으면, element() 함수는 유효하지 않은 이미지를 나타냅니다.
- ID가 맵에서 전혀 발견되지 않으면, 일반적으로 문서에서 검색합니다.
이 ID 선택자 재사용은 Moz의 동작과 일치합니다. 문법 시작 부분에 <custom-ident>를 넣는 것은 너무 많은 문법 공간을 점유하므로 피하고 싶습니다. 또 다른 대안은 값 시작을 언어 정의 키워드 다음에 <custom-ident>가 오도록 하는 것입니다. 예: element(external fancy)와 같이. 네이밍 제안 환영합니다.
< script > var bg= document. createElement( 'canvas' ); bg. height= 200 ; bg. width= 1000 ; drawFancyBackground( bg); CSS. elementSources. set( 'fancy' , bg); </ script > < style > h1 { background-image : element ( #fancy ); } </ style >
"fancy" 캔버스가 그려지고 애니메이션되면, 모든 H1 요소의 배경도 자동으로 동기화되어 업데이트됩니다.
elementSources 맵이 ID 선택자와 일치시키기 위해 문서보다 먼저 참조됨에 주의하세요. 즉, 문서에 #fancy에 해당하는 요소가 있어도, 배경은 항상 elementSources 값에서 예측 가능하게 가져옵니다.
2.7.3. 순환 감지(Cycle Detection)
element() 함수는 자기 자신을 배경으로 사용하는 등 터무니없는 순환 관계를 만들 수 있습니다. 하지만 의존성 그래프를 추적하고 일반적인 순환 감지 알고리즘을 사용하면 이런 관계도 쉽게 신뢰성 있게 감지하고 해결할 수 있습니다.
의존성 그래프의 엣지는 다음과 같이 구성됩니다:
- 모든 요소는 자신의 자식에 의존합니다
- element() 함수가 있는 속성이 요소 A에서 요소 B를 가리키면, A는 B에 의존합니다
- 호스트 언어가 다른 요소의 렌더링을 참조하는 방법을 정의하면,
참조하는 요소는 참조된 요소에 의존합니다.
예: SVG에서
<use>
요소는 참조 대상에 의존합니다.
그래프에 순환이 있으면, 해당 순환에 참여하는 element() 함수는 유효하지 않은 이미지가 됩니다.
3. 그라디언트
그라디언트는 한 색상에서 다른 색상으로 부드럽게 전환되는 이미지입니다. 이는 배경 이미지, 버튼 등에서 미묘한 음영 효과를 주기 위해 자주 사용됩니다. 이 섹션에서 설명하는 그라디언트 함수를 사용하면 작성자가 간결한 문법으로 이러한 이미지를 지정할 수 있으며, UA가 페이지 렌더링 시 이미지를 자동으로 생성할 수 있습니다. <gradient>의 문법은 다음과 같습니다:
<gradient> =[ <linear-gradient () > | <repeating-linear-gradient () > | <radial-gradient () > | <repeating-radial-gradient () > | <conic-gradient () > | <repeating-conic-gradient () >]
이 명세에서 정의된 다른 <image> 타입과 마찬가지로, 그라디언트는 이미지를 허용하는 모든 속성에서 사용할 수 있습니다. 예시:
background : linear-gradient ( white, gray); list-style-image : radial-gradient ( circle, #006, #00a90 % , #0000af100 % , white100 % )
그라디언트는 구체적 오브젝트 크기의 치수를 가진 박스에 그려지며, 이를 그라디언트 박스라고 부릅니다. 단, 그라디언트 자체는 자연 치수를 가지지 않습니다.
그라디언트는 시작점과 끝점을 지정하고, 그라디언트 선 위(그라디언트 타입에 따라 직선, 반직선, 나선 등일 수 있음)에 색상을 지정하여 만듭니다. 색상은 이 선을 따라 부드럽게 혼합되며, 각 그라디언트 타입은 그라디언트 선의 색상을 실제 그라디언트로 만드는 방법을 정의합니다.
3.1. 선형 그라디언트: linear-gradient() 표기법
이 레벨에서는 <color-interpolation-method> 인자가 linear-gradient()와 repeating-linear-gradient()에 추가되어, 그라디언트 선에서 색상을 보간할 때 사용할 색상 공간과 경로를 지정할 수 있습니다. 자세한 내용은 CSS Color 4 § 12. 색상 보간을 참고하세요.
<linear-gradient-syntax> =[ [ <angle> | <zero> | to <side-or-corner>] || <color-interpolation-method>] ?, <color-stop-list> <side-or-corner> =[ left | right] ||[ top | bottom]
테스트
- color-stop-currentcolor.html (실시간 테스트) (소스)
- gradient-border-box.html (실시간 테스트) (소스)
- gradient-button.html (실시간 테스트) (소스)
- gradient-content-box.html (실시간 테스트) (소스)
- linear-gradient-1.html (실시간 테스트) (소스)
- linear-gradient-2.html (실시간 테스트) (소스)
- linear-gradient-body-sibling-index.html (실시간 테스트) (소스)
- linear-gradient-calc-em-units.html (실시간 테스트) (소스)
- linear-gradient-non-square.html (실시간 테스트) (소스)
- linear-gradient-sibling-index.html (실시간 테스트) (소스)
- multiple-position-color-stop-linear-2.html (실시간 테스트) (소스)
- multiple-position-color-stop-linear.html (실시간 테스트) (소스)
- normalization-linear-2.html (실시간 테스트) (소스)
- normalization-linear-degenerate.html (실시간 테스트) (소스)
- normalization-linear.html (실시간 테스트) (소스)
- tiled-gradients.html (실시간 테스트) (소스)
- color-stops-parsing.html (실시간 테스트) (소스)
- linear-gradient-relative-currentcolor-stop.html (실시간 테스트) (소스)
- gradient-single-stop-001.html (실시간 테스트) (소스)
- gradient-single-stop-002.html (실시간 테스트) (소스)
- gradient-single-stop-003.html (실시간 테스트) (소스)
- gradient-single-stop-004.html (실시간 테스트) (소스)
- gradient-single-stop-005.html (실시간 테스트) (소스)
- gradient-single-stop-006.html (실시간 테스트) (소스)
- gradient-single-stop-007.html (실시간 테스트) (소스)
- gradient-single-stop-008.html (실시간 테스트) (소스)
- gradient-single-stop-longer-hue-hsl-002.html (실시간 테스트) (소스)
- gradient-single-stop-longer-hue-hsl.html (실시간 테스트) (소스)
- gradient-single-stop-longer-hue-oklch.html (실시간 테스트) (소스)
- gradient-single-stop-none-interpolation.html (실시간 테스트) (소스)
- gradient-interpolation-method-computed.html (실시간 테스트) (소스)
- gradient-interpolation-method-invalid.html (실시간 테스트) (소스)
- gradient-interpolation-method-valid.html (실시간 테스트) (소스)
- gradient-position-invalid.html (실시간 테스트) (소스)
- gradient-position-valid.html (실시간 테스트) (소스)
3.1.1. 색상 공간의 보간 효과: 예시
이 섹션은 규범적이지 않습니다.
색상 공간이 보간에 미치는 영향은 상당할 수 있습니다.
linear-gradient ( in lab to right, #F01, #081) linear-gradient ( in srgb to right, #F01, #081) linear-gradient ( in Oklab to right, #F01, #081)
linear-gradient ( in lab to right, white, #01E) linear-gradient ( in srgb to right, white, #01E) linear-gradient ( in Oklab to right, white, #01E)
linear-gradient ( in lab to right, #44C, #795) linear-gradient ( in srgb to right, #44C, #795) linear-gradient ( in Oklab to right, #44C, #795)
그라디언트 보간에서 직교(rectangular)가 아닌 극좌표(polar) 색상 공간을 선택하면 색상 중지점의 색상차가 멀 경우 탈포화를 피할 수 있습니다. 극좌표 색상 공간에서 보간하면 본질적으로 채도를 보존하지만, 중간색이 색 영역을 벗어나기 쉽습니다; 이 경우 색 영역에 맞게 매핑됩니다.
직교 공간에서는 중간값이 회색빛을 띠지만, 극좌표 공간에서는 중간색이 곡선 형태의 채도 보존 경로를 따릅니다.
linear-gradient ( in lch to right, #A37, #595) linear-gradient ( in lab to right, #A37, #595) linear-gradient ( in srgb to right, #A37, #595) linear-gradient ( in Oklab to right, #A37, #595) linear-gradient ( in oklch to right, #A37, #595)
3.2. 방사형 그라디언트: radial-gradient() 표기법
3.2.1. <color-interpolation-method> 추가
이 레벨에서는 <color-interpolation-method> 인자가 radial-gradient()와 repeating-radial-gradient()에 추가되어, 그라디언트 선에서 색상 보간 시 사용할 색상 공간과 경로를 지정할 수 있습니다. 자세한 내용은 CSS Color 4 § 12. 색상 보간을 참고하세요.
<radial-gradient-syntax> =[ [ [ <radial-shape> || <radial-size>] ?[ at <position>] ?] || <color-interpolation-method>] ?, <color-stop-list>
테스트
- empty-radial-gradient-crash.html (실시간 테스트) (소스)
- infinite-radial-gradient-refcrash.html (실시간 테스트) (소스)
- multiple-position-color-stop-radial-2.html (실시간 테스트) (소스)
- multiple-position-color-stop-radial.html (실시간 테스트) (소스)
- normalization-radial-2.html (실시간 테스트) (소스)
- normalization-radial-3.html (실시간 테스트) (소스)
- normalization-radial-4.html (실시간 테스트) (소스)
- normalization-radial-degenerate.html (실시간 테스트) (소스)
- normalization-radial.html (실시간 테스트) (소스)
- radial-gradient-container-relative-units-001.html (실시간 테스트) (소스)
- radial-gradient-container-relative-units-002.html (실시간 테스트) (소스)
- radial-gradient-container-relative-units-003.html (실시간 테스트) (소스)
- radial-gradient-container-relative-units-004.html (실시간 테스트) (소스)
- radial-gradient-transition-hint-crash.html (실시간 테스트) (소스)
- tiled-radial-gradients.html (실시간 테스트) (소스)
- color-stops-parsing.html (실시간 테스트) (소스)
- gradient-interpolation-method-computed.html (실시간 테스트) (소스)
- gradient-interpolation-method-invalid.html (실시간 테스트) (소스)
- gradient-interpolation-method-valid.html (실시간 테스트) (소스)
- gradient-position-invalid.html (실시간 테스트) (소스)
- gradient-position-valid.html (실시간 테스트) (소스)
radial-gradient ( in lab farthest-side at left bottom, color ( display-p30.918 0.2 0.161 ), #081) radial-gradient ( in srgb farthest-side at left bottom, color ( display-p30.918 0.2 0.161 ), #081) radial-gradient ( in Oklab farthest-side at left bottom, color ( display-p30.918 0.2 0.161 ), #081)
3.2.2. <radial-size> 확장
이 레벨에서는 <radial-size> 옵션을 circle() 및 ellipse() <basic-shape> 값의 추가를 포함하여 확장합니다:
<radial-size> = <radial-extent>{ 1 , 2 } | <length-percentage[ 0 , ∞] >{ 1 , 2 }
두 개의 값을 사용하는 경우 circle을 <radial-shape>로 지정했을 때는 여전히 유효하지 않으며, 그 외에는 각각 타원의 수평(첫 번째) 및 수직(두 번째) 반지름을 나타냅니다.
circle의 경우,
<percentage> 값은
gradient box의 너비와 높이에 대한 "스케일된
대각선"을 기준으로 해석됩니다:
.
3.3. 원뿔형 그라디언트: conic-gradient() 표기법
원뿔형 그라디언트는 중심점을 지정하는 것부터 시작합니다. 이는 방사형 그라디언트와 비슷하지만, 원뿔형 그라디언트의 컬러 스톱은 원의 둘레를 따라 배치되며, 중심에서 방사되는 선이 아니라 중심을 중심으로 회전하면서 색상이 부드럽게 변화합니다. 즉, 중심에서 바깥 방향이 아니라, 원을 따라 도는 각도로 색이 전환됩니다.
원뿔형 그라디언트는 회전 각도, 그라디언트의 중심, 그리고 컬러 스톱 목록을 지정하여 정의합니다. 선형 및 방사형 그라디언트와는 달리, 컬러 스톱의 위치를 <length>로 지정하지 않고, 원뿔형 그라디언트의 컬러 스톱은 <angle>로 지정합니다. 중심에서 모든 방향으로 방사선이 그려지며, 각 방사선의 색상은 그라디언트 선과 교차하는 지점의 색상입니다.
참고: 이러한 그라디언트가 "conic" 또는 "conical"이라 불리는 이유는, 컬러 스톱을 한 쪽이 훨씬 밝게 배치하면 위에서 본 원뿔 모양의 패턴이 나타나기 때문입니다. 또한 일부 맥락에서는 "각도(angle) 그라디언트"로도 불리는데, 이는 방사선의 회전 각도를 바꿔서 그라디언트를 생성하기 때문입니다.
3.3.1. conic-gradient() 문법
원뿔형 그라디언트의 문법은 다음과 같습니다:
conic-gradient () =conic-gradient ( [ <conic-gradient-syntax>] ) <conic-gradient-syntax> =[ [ [ from[ <angle> | <zero>] ] ?[ at <position>] ?] || <color-interpolation-method>] ?, <angular-color-stop-list>
각 인자는 다음과 같이 정의됩니다:
- <angle> | <zero>
- 전체 그라디언트가 이 각도만큼 회전합니다. 생략 시 기본값은 0deg입니다. <angle>이 0이면 단위 식별자를 생략할 수 있습니다.
- <position>
- 그라디언트의 그라디언트 중심을 결정합니다. <position> 값 타입(이 타입은 background-position에도 사용됨)은 [CSS-VALUES-3]에서 정의되어 있으며, 중심점을 오브젝트 영역으로, gradient box를 포지셔닝 영역으로 하여 해석됩니다. 생략 시 center가 기본값입니다.
원뿔형 그라디언트에서 0deg에서의 날카로운 전환은 보통 원하지 않는 결과이며, 일반적으로 첫 번째와 마지막 컬러 스톱을 같은 색상으로 맞춰서 피합니다. 이를 자동으로 달성하는 키워드가 있으면 유용할 수 있습니다.
그라디언트의 클리핑을 위한 반지름(내부 및 외부)이 유용할까요? 그렇다면 컬러 스톱 위치에 길이도 지원할 수 있을 것입니다.
타원형 원뿔형 그라디언트가 유용할까요? 그래픽 라이브러리들이 이를 지원하나요?
테스트
- conic-gradient-001.html (실시간 테스트) (소스)
- conic-gradient-angle-negative.html (실시간 테스트) (소스)
- conic-gradient-angle.html (실시간 테스트) (소스)
- conic-gradient-center.html (실시간 테스트) (소스)
- repeating-conic-gradient.html (실시간 테스트) (소스)
- tiled-conic-gradients.html (실시간 테스트) (소스)
- multiple-position-color-stop-conic-2.html (실시간 테스트) (소스)
- multiple-position-color-stop-conic.html (실시간 테스트) (소스)
- normalization-conic-2.html (실시간 테스트) (소스)
- normalization-conic-degenerate.html (실시간 테스트) (소스)
- normalization-conic.html (실시간 테스트) (소스)
- out-of-range-color-stop-conic.html (실시간 테스트) (소스)
- tiled-conic-gradients.html (실시간 테스트) (소스)
- color-stops-parsing.html (실시간 테스트) (소스)
- gradient-interpolation-method-computed.html (실시간 테스트) (소스)
- gradient-interpolation-method-invalid.html (실시간 테스트) (소스)
- gradient-interpolation-method-valid.html (실시간 테스트) (소스)
- gradient-position-invalid.html (실시간 테스트) (소스)
- gradient-position-valid.html (실시간 테스트) (소스)
3.3.2. 색상 중지점 배치
색상 중지점(color stop)은 그라디언트 선 위에 배치되며, 이 선은 그라디언트 중심을 원형으로 감쌉니다. 0%와 100% 위치 모두 0deg에 해당합니다. 선형 그라디언트와 마찬가지로, 0deg는 페이지의 맨 위를 가리키며, 각도가 증가할수록 시계 방향으로 원을 따라 이동합니다.
참고: 그라디언트 선을 나선형(spiral)으로 생각하고, 0deg~360deg 구간만 렌더링된다고 생각하면 더 이해하기 쉬울 수 있습니다. 이렇게 하면 렌더링 영역 바깥의 각도에서 "겹침"에 대한 혼동을 피할 수 있습니다.
색상 중지점은 0% 이전이나 100% 이후 위치에도 배치할 수 있습니다; 이 영역은 직접적으로 렌더링에 사용되지 않지만, 그곳에 배치된 중지점이 보간 또는 반복을 통해 렌더링 영역 내의 중지점 색상에 영향을 줄 수 있습니다(repeating gradients 참고). 예를 들어, conic-gradient(red -50%, yellow 150%)는 0deg에서 붉은 오렌지색(#f50)으로 시작해 360deg에서 주황빛 노란색(#fa0)으로 바뀌는 원뿔 그라디언트를 만듭니다.
그라디언트의 임의 지점의 색상은 먼저 해당 지점을 지나는 중심(anchor)에서 출발하는 유일한 방사선을 찾은 뒤, 이 방사선이 그라디언트 선과 만나는 위치의 색상을 사용하는 방식으로 결정됩니다.
3.3.3. 원뿔형 그라디언트 예시
아래 모든 conic-gradient() 예시는 별도 명시가 없는 한 300px 너비, 200px 높이의 박스에 적용된다고 가정합니다.
background : conic-gradient ( #f06, gold); background : conic-gradient ( at50 % 50 % , #f06, gold); background : conic-gradient ( from0 deg , #f06, gold); background : conic-gradient ( from0 deg at center, #f06, gold); background : conic-gradient ( #f060 % , gold100 % ); background : conic-gradient ( #f060 deg , gold1 turn );
background : conic-gradient ( white-50 % , black150 % ); background : conic-gradient ( white-180 deg , black540 deg ); background : conic-gradient ( hsl ( 0 , 0 % , 75 % ), hsl ( 0 , 0 % , 25 % ));
background : conic-gradient ( from45 deg , white, black, white); background : conic-gradient ( hsl ( 0 , 0 % , 75 % ), white45 deg , black225 deg , hsl ( 0 , 0 % , 75 % ));
모든 컬러 스톱을 회전 각도만큼 오프셋하는 식으로 지정하면 동일한 효과가 아니라 완전히 다른 그라디언트가 만들어집니다:
background : conic-gradient ( white45 deg , black225 deg , white405 deg );
background : radial-gradient ( closest-side, gray, transparent), conic-gradient ( red, magenta, blue, aqua, lime, yellow, red); border-radius : 50 % ; width : 200 px ; height : 200 px ;
同じ 효과를 "longer" hue 보간을 사용해 더 간결하게 얻을 수 있습니다. 이 방법은 다른 색상 공간으로 전환하기도 쉽습니다.
background : radial-gradient ( closest-side, gray, transparent), conic-gradient ( in hsl longer hue, red0 100 % ); transform : scaleX ( -1 ); border-radius : 50 % ; width : 200 px ; height : 200 px ;
background : conic-gradient ( yellowgreen40 % , gold0 deg 75 % , #f060 deg ); border-radius : 50 % ; width : 200 px ; height : 200 px ;
3.4. 반복 그라디언트: repeating-linear-gradient(), repeating-radial-gradient(), repeating-conic-gradient() 표기법
linear-gradient(), radial-gradient(), conic-gradient() 외에도, 이 명세는 repeating-linear-gradient(), repeating-radial-gradient(), repeating-conic-gradient() 값을 정의합니다. 이 표기법들은 동일한 값을 받고, 각각의 비반복 함수와 동일하게 해석됩니다.
<repeating-conic-gradient () > =repeating-conic-gradient ( [ <conic-gradient-syntax>] ) <repeating-linear-gradient () > =repeating-linear-gradient ( [ <linear-gradient-syntax>] ) <repeating-radial-gradient () > =repeating-radial-gradient ( [ <radial-gradient-syntax>] )
테스트
background : repeating-conic-gradient ( hsla ( 0 , 0 % , 100 % , .2 ) 0 deg 15 deg , hsla ( 0 , 0 % , 100 % , 0 ) 0 deg 30 deg ) #0ac;
background : repeating-conic-gradient ( black0 deg 25 % , white0 deg 50 % ); background-size : 60 px 60 px ;
동일한 체커보드는 비반복 원뿔형 그라디언트로도 만들 수 있습니다:
background : conic-gradient ( black25 % , white0 deg 50 % , black0 deg 75 % , white0 deg ); background-size : 60 px 60 px ;
3.5. 그라디언트 색상 정의
그라디언트에서 색상은 색상 중지점(color stop)(<color>와 그라디언트 선에서의 위치)과 색상 전환 힌트(transition hint)(두 색상 중지점 사이의 전환 중간지점) 으로 지정하며, 이들은 그라디언트 선에 배치되어 선의 모든 지점의 색을 정의합니다. (각 그라디언트 함수는 그라디언트 선의 모양과 길이, 시작점과 끝점을 정의합니다. 위 내용을 참고하세요.)
그라디언트 필드 전체의 색상은, 그라디언트 함수가 지정한 대로 그라디언트 선의 특정 위치에 연결함으로써 결정됩니다. UA는 그라디언트 색상을 "디더링"(gradient 선의 인접색을 픽셀마다 무작위로 교차 사용)하여 더 부드럽게 보이도록 처리할 수 있습니다.
3.5.1. 색상 중지점 리스트
색상 중지점과 전환 힌트는 색상 중지점 리스트로 지정되며, 이는 하나 이상의 색상 중지점과 선택적 전환 힌트가 교차된 형태의 리스트입니다:
<color-stop-list> = <linear-color-stop>, [ <linear-color-hint>?, <linear-color-stop>] #? <linear-color-stop> = <color> <color-stop-length>? <linear-color-hint> = <length-percentage> <color-stop-length> = <length-percentage>{ 1 , 2 } <angular-color-stop-list> = <angular-color-stop>, [ <angular-color-hint>?, <angular-color-stop>] #? <angular-color-stop> = <color> <color-stop-angle>? <angular-color-hint> = <angle-percentage> | <zero> <color-stop-angle> =[ <angle-percentage> | <zero>] { 1 , 2 } <color-stop> = <color-stop-length> | <color-stop-angle>
테스트
- color-stops-parsing.html (실시간 테스트) (소스)
- gradient-single-stop-001.html (실시간 테스트) (소스)
- gradient-single-stop-002.html (실시간 테스트) (소스)
- gradient-single-stop-003.html (실시간 테스트) (소스)
- gradient-single-stop-004.html (실시간 테스트) (소스)
- gradient-single-stop-005.html (실시간 테스트) (소스)
- gradient-single-stop-006.html (실시간 테스트) (소스)
- gradient-single-stop-007.html (실시간 테스트) (소스)
- gradient-single-stop-008.html (실시간 테스트) (소스)
- gradient-single-stop-longer-hue-hsl-002.html (실시간 테스트) (소스)
- gradient-single-stop-longer-hue-hsl.html (실시간 테스트) (소스)
- gradient-single-stop-longer-hue-oklch.html (실시간 테스트) (소스)
- gradient-single-stop-none-interpolation.html (실시간 테스트) (소스)
레일로드 다이어그램으로 시각화하면, 둘 다 다음 패턴을 따릅니다:
두 위치가 지정된 색상 중지점은, 같은 색상으로 두 위치에 색상 중지점을 각각 지정한 것과 동일합니다.
참고: 보통 이렇게 하면 두 위치 사이가 단색 "스트라이프"로 나타나지만, longer <color-interpolation-method>를 사용하면 두 위치 사이에 "무지개" 효과가 만들어집니다.
퍼센트 값은 시작점과 끝점 사이의 그라디언트 선의 길이에 대해 해석되며, 0%는 시작점, 100%는 끝점에 해당합니다. 길이는 그라디언트 선을 따라 시작점에서 끝점 방향으로 측정됩니다.
색상 중지점과 전환 힌트의 위치는 보통 시작점과 끝점 사이에 지정되지만, 반드시 그럴 필요는 없습니다: 그라디언트 선은 양쪽 방향으로 무한히 확장되며, 위치는 그라디언트 선 어디든 지정할 수 있습니다.
색상 중지점의 위치가 생략된 경우, 위치가 자동으로 할당됩니다. 색상 중지점 리스트의 맨 처음이나 마지막 색상 중지점은 각각 그라디언트 선의 시작점 또는 끝점에 할당됩니다. 그렇지 않은 경우, 주변 두 중지점의 중간 위치로 할당됩니다. 연속으로 여러 개의 중지점에 위치가 없는 경우, 주변에 위치가 지정된 중지점 사이에 동일한 간격으로 배분됩니다. 자세한 내용은 § 3.5.3 색상 중지점 "Fixup"을 참고하세요.
3.5.2. 그라디언트 선 채색
각 색상 중지점 위치에서 그라디언트 선의 색상은 해당 색상 중지점의 색입니다. 첫 번째 색상 중지점 이전에는 그라디언트 선의 색이 첫 색상 중지점의 색이고, 마지막 색상 중지점 이후에는 그라디언트 선의 색이 마지막 색상 중지점의 색입니다. 각 색상 중지점 쌍 사이에서는 그라디언트 선의 색이 두 색상 중지점의 색상 사이에서 보간되며, 보간은 지정된 색상 공간에서 일어납니다. 누락된 색상 성분은 CSS Color 4 § 12.2 Interpolating with Missing Components에 따라 처리되고, 색상환 보간(hue interpolation)은 CSS Color 4 § 12.4 Hue Interpolation에 따라, 프리멀티플라이드 알파(premultiplied alpha)는 CSS Color 4 § 12.3 Interpolating with Alpha에 따라 처리됩니다. 그라디언트 함수에서 <color-interpolation-method>가 지정되지 않은 경우, 그라디언트 보간에 사용되는 색상 공간은 [css-color-4]에서 정의된 기본 보간 색상 공간인 Oklab입니다.
참고: <color-interpolation-method>는 중지점 사이의 색상에만 영향을 줍니다. 첫 번째 이전, 마지막 이후의 색상은 보간 방식과 무관하게 각각 첫/마지막 중지점의 색상과 동일합니다.
테스트
- gradients-with-transparent.html (실시간 테스트) (소스)
- gradient-analogous-missing-components-001.html (실시간 테스트) (소스)
- gradient-analogous-missing-components-002.html (실시간 테스트) (소스)
- gradient-analogous-missing-components-003.html (실시간 테스트) (소스)
- gradient-analogous-missing-components-004.html (실시간 테스트) (소스)
- css-color-4-colors-default-to-oklab-gradient.html (실시간 테스트) (소스)
- gradient-decreasing-hue-hsl.html (실시간 테스트) (소스)
- gradient-decreasing-hue-lch.html (실시간 테스트) (소스)
- gradient-eval-predefined-color-spaces.html (실시간 테스트) (소스)
- gradient-eval-001.html (실시간 테스트) (소스)
- gradient-eval-002.html (실시간 테스트) (소스)
- gradient-eval-003.html (실시간 테스트) (소스)
- gradient-eval-004.html (실시간 테스트) (소스)
- gradient-eval-005.html (실시간 테스트) (소스)
- gradient-eval-006.html (실시간 테스트) (소스)
- gradient-eval-007.html (실시간 테스트) (소스)
- gradient-eval-008.html (실시간 테스트) (소스)
- gradient-eval-009.html (실시간 테스트) (소스)
- gradient-eval-010.html (visual test) (소스)
- gradient-none-interpolation.html (실시간 테스트) (소스)
- gradient-to-transparent.html (실시간 테스트) (소스)
- legacy-color-gradient.html (실시간 테스트) (소스)
- oklab-gradient.html (실시간 테스트) (소스)
- srgb-gradient.html (실시간 테스트) (소스)
- srgb-linear-gradient.html (실시간 테스트) (소스)
- xyz-gradient.html (실시간 테스트) (소스)
- color-scheme-dependent-color-stops.html (실시간 테스트) (소스)
- gradient-hue-direction.html (실시간 테스트) (소스)
- gradient-increasing-hue-hsl.html (실시간 테스트) (소스)
- gradient-increasing-hue-lch.html (실시간 테스트) (소스)
- gradient-infinity-001.html (실시간 테스트) (소스)
- gradient-infinity-002.html (실시간 테스트) (소스)
- gradient-infinity-003.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-001.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-002.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-003.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-004.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-005.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-006.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-007.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-008.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-009.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-010.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-011.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-012.html (실시간 테스트) (소스)
- gradient-longer-hue-hsl-013.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-001.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-002.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-003.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-004.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-005.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-006.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-007.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-008.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-009.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-010.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-011.html (실시간 테스트) (소스)
- gradient-longer-hue-lch-012.html (실시간 테스트) (소스)
- gradient-powerless-hue-hsl.html (실시간 테스트) (소스)
- gradient-powerless-hue-hwb.html (실시간 테스트) (소스)
- gradient-powerless-hue-lch.html (실시간 테스트) (소스)
- gradient-powerless-hue-oklch.html (실시간 테스트) (소스)
linear-gradient ( in oklch, red, #888, green)
중간색 #888을 oklch로 변환하면 색상(hue) 성분이 없는 상태가 됩니다: oklch(0.6268 0 none)
따라서 첫 번째 그라디언트 구간에서는 색상(hue)이 빨간색에서 가져오며, 빨간색은 oklch(0.628 0.2577 29.234)입니다; 두 번째 구간에서는 초록색에서 가져온 hue를 사용하며, 초록색은 oklch(0.5198 0.1769 142.5)입니다.
기본적으로 이 보간은 선형입니다. 즉, 두 색상 중지점 사이 거리의 25%, 50%, 75% 지점에서의 색상은 두 중지점의 색을 25%, 50%, 75%로 섞은 색이 됩니다.
하지만 두 색상 중지점 사이에 전환 힌트가 주어진 경우, 보간은 비선형이 되며, 힌트에 의해 제어됩니다:
참고: 전환 힌트는 두 색상 중지점 사이 색상의 "중간색"(50% 혼합)이 어디에 위치할지 지정합니다. 힌트가 두 중지점의 정확히 중간에 있다면, 위 보간 알고리즘은 일반적인 선형 보간과 동일합니다. 힌트가 다른 곳에 있다면, 그 구간에서 부드러운 지수 곡선을 만들고, "중간색"이 힌트 위치에 정확히 오게 됩니다.
위 - 전환 힌트 없이(기본값인 중간 위치):
background : linear-gradient ( to right, red0 % , blue100 % );
아래 - 전환 힌트 사용:
background : linear-gradient ( to right, red0 % , 25 % , blue100 % );
여러 색상 중지점의 위치가 같으면, 리스트에서 먼저 지정된 색에서 마지막에 지정된 색으로 순간적으로(무한소 간격으로) 전환이 발생합니다. 즉, 해당 위치에서 색상이 부드럽게 바뀌지 않고 갑자기 바뀌게 됩니다.
3.5.3. 색상 중지점 “정정(Fixup)”
각 사용된 색상 중지점의 위치를 결정할 때, 아래 단계들을 순서대로 적용해야 합니다:
- 첫 번째 색상 중지점에 위치가 지정되지 않았다면, 그 위치를 0%로 설정합니다.
- 마지막 색상 중지점에 위치가 지정되지 않았다면, 그 위치를 100%로 설정합니다.
- 어떤 색상 중지점 또는 전환 힌트의 위치가 리스트에서 그 앞에 있는 색상 중지점이나 전환 힌트의 지정 위치보다 작을 경우, 그 위치를 리스트에서 앞에 있는 모든 색상 중지점 또는 전환 힌트의 지정 위치 중 가장 큰 값과 동일하게 맞춥니다.
- 여전히 위치가 지정되지 않은 색상 중지점이 있다면, 위치가 없는 인접 색상 중지점들의 구간마다, 그 앞뒤에 위치가 지정된 색상 중지점들 사이에 균등하게 배분하여 위치를 할당합니다.
이 규칙을 모두 적용한 뒤에는, 모든 색상 중지점과 전환 힌트는 명확한 위치와 색상을 가지며, 위치가 오름차순으로 정렬됩니다.
테스트
참고: 작성자는 px, em, % 등 여러 단위 유형을 혼합해서 사용할 때 주의해야 합니다. 서로 다른 단위를 혼합하면 색상 중지점이 앞선 중지점보다 앞서 배치되는 등 의도치 않은 결과가 발생할 수 있습니다. 예를 들어, 규칙 background-image: linear-gradient(yellow 100px, blue 50%)는 배경 영역의 높이가 200px 이상이면 fix-up이 발생하지 않습니다. 하지만 높이가 150px이라면, 파란색 색상 중지점의 위치는 75px에 해당하여 노란색 색상 중지점보다 앞서게 되므로, 이 위치가 100px로 보정(fixup)됩니다. 또한 이런 색상 중지점들의 상대적 순서는 레이아웃을 실제로 해보기 전까지는 알 수 없으므로, 애니메이션이나 트랜지션에서는 부드럽게 보간되지 않습니다.
1 .linear-gradient ( red, white20 % , blue) =1 =>linear-gradient ( red0 % , white20 % , blue100 % ) 2 .linear-gradient ( red40 % , white, black, blue) =1 , 3 =>linear-gradient ( red40 % , white60 % , black80 % , blue100 % ) 3 .linear-gradient ( red-50 % , white, blue) =1 , 3 =>linear-gradient ( red-50 % , white25 % , blue100 % ) 4 .linear-gradient ( red-50 px , white, blue) =1 , 3 =>linear-gradient ( red-50 px , whitecalc ( -25 px +50 % ), blue100 % ) 5 .linear-gradient ( red20 px , white0 px , blue40 px ) =2 =>linear-gradient ( red20 px , white20 px , blue40 px ) 6 .linear-gradient ( red, white-50 % , black150 % , blue) =1 , 2 =>linear-gradient ( red0 % , white0 % , black150 % , blue150 % ) 7 .linear-gradient ( red80 px , white0 px , black, blue100 px ) =2 , 3 =>linear-gradient ( red80 px , white80 px , black90 px , blue100 px )
4. 1D 이미지 값: <image-1D> 타입과 stripes() 표기법
<image> 값은 2차원(2D) 이미지를, <color>는 0차원(0D) 이미지(어느 축에서도 변하지 않음)로 볼 수 있지만, 어떤 맥락에서는 1차원(1D) 이미지가 필요합니다. 이는 추상적이고 방향이 없는 단일 축의 페인트 선(paint line)을 따라 색상을 지정합니다. <image-1D> 타입은 이런 1D 이미지를 나타내며, stripes() 함수 표기법이 포함됩니다:
<image-1D> = <stripes () > <stripes () > =stripes ( <color-stripe>#) <color-stripe> = <color> &&[ <length-percentage> | <flex>] ?
stripes() 함수는 1D 이미지를 색상 줄무늬(스트라이프)들의 콤마로 구분된 리스트로 정의하며, 각각의 줄무늬는 지정된 순서대로 페인트 선에 이어서 배치됩니다.
각 <color-stripe> 항목은 지정된 <color>와 두께를 가진 단색 스트라이프를 정의합니다. 두께가 생략되면 기본값은 1fr입니다. 두께는 다음과 같이 해석합니다:
- <percentage [0,100]>
- 퍼센트 두께는 전체 너비에 대해 상대적으로 적용됩니다. 0%~100% 사이 값만 유효합니다.
- <length [0,∞]>
- 음수 길이 값은 유효하지 않습니다.
- <flex>
- <flex>는 전체 너비에서 <flex> 항목들의 총합에 대해 비율로 나눠 집니다. non-<flex> 항목의 두께를 전체 너비에서 뺀 뒤(음수면 0으로 바닥 처리), <flex> 값의 합이 1fr보다 작으면, 뺀 결과에 합값을 곱한 뒤 비율로 배분합니다.
전체 너비는 stripes() 함수가 사용되는 맥락에서 정의됩니다. 줄무늬 합이 전체 너비보다 작으면, 페인트 선의 나머지 길이는 투명 검정이 되며, 마지막에 transparent 인자를 준 것과 같습니다. 합이 더 크면, 전체 너비를 넘는 줄무늬나 그 일부는 잘려서 표시되지 않습니다.
반면 stripes(red .1fr, green .2fr, blue 100px)에 전체 너비가 400px이면, 빨강 30px, 초록 60px, 파랑 100px, 나머지 210px은 투명이 됩니다. 남은 300px에 <flex> 값의 합 0.3을 곱해 90px만 분배되고, 나머지는 투명으로 채워집니다.
(이것은 flex 레이아웃에서 한 줄에 <flex> 총합이 작을 때와 비슷하며, <flex> 값이 0에 가까워질 때도 부드럽게 연속적인 동작을 보장합니다.)
이 함수의 계산값(computed value)은 각 줄무늬가 계산된 색상과 <flex> 값 또는 계산된 <length-percentage> 값으로 된 스트라이프 리스트입니다.
5. CSS에서 이미지 및 오브젝트 크기 조정
5.1. 오브젝트 크기 조정: object-fit 속성
이름: | object-fit |
---|---|
값: | fill | none | [contain | cover] || scale-down |
기본값: | fill |
적용 대상: | 대체 요소(replaced elements) |
상속 여부: | 아니오 |
퍼센트 값: | 해당 없음 |
계산값: | 지정된 키워드 |
정규 순서: | 문법에 따름 |
애니메이션 타입: | 불연속(discrete) |
object-fit 속성은 대체 요소의 콘텐츠가 해당 요소의 사용된 높이와 너비로 만들어진 박스에 어떻게 맞춰질지 지정합니다.
- fill
- 대체 콘텐츠가 요소의 content box를 가득 채우도록 크기가 조정됩니다: 오브젝트의 구체 오브젝트 크기는 해당 요소의 사용된 너비와 높이입니다.
- none
- 대체 콘텐츠가 요소의 content box에 맞게 크기가 조정되지 않습니다: 기본 크기 산정 알고리즘을 크기 미지정 상태로 사용하여 구체 오브젝트 크기를 결정하며, 기본 오브젝트 크기는 대체 요소의 사용된 너비와 높이와 같습니다.
- contain
-
대체 콘텐츠가 요소의 content box 안에 들어가면서
종횡비(aspect ratio)를 유지하도록 크기가 조정됩니다:
그 구체 오브젝트 크기는 요소의 사용된 너비와 높이에 대해 contain 제약으로 계산됩니다.
scale-down 플래그를 사용할 경우, 콘텐츠 크기를 none 또는 contain 중 더 작은 구체 오브젝트 크기를 만드는 쪽으로 정합니다.
- cover
-
대체 콘텐츠가 요소의 content box 전체를 채우면서
종횡비를 유지하도록 크기가 조정됩니다:
구체 오브젝트 크기는 요소의 사용된 너비와 높이에 대해 cover
제약으로 계산됩니다.
scale-down 플래그를 사용할 경우, 콘텐츠 크기를 none 또는 cover 중 더 작은 구체 오브젝트 크기를 만드는 쪽으로 정합니다.
- scale-down
- contain scale-down과 동일합니다.
테스트
- inheritance.html (실시간 테스트) (소스)
- object-fit-contain-png-001c.html (실시간 테스트) (소스)
- object-fit-contain-png-001e.html (실시간 테스트) (소스)
- object-fit-contain-png-001i.html (실시간 테스트) (소스)
- object-fit-contain-png-001o.html (실시간 테스트) (소스)
- object-fit-contain-png-001p.html (실시간 테스트) (소스)
- object-fit-contain-png-002c.html (실시간 테스트) (소스)
- object-fit-contain-png-002e.html (실시간 테스트) (소스)
- object-fit-contain-png-002i.html (실시간 테스트) (소스)
- object-fit-contain-png-002o.html (실시간 테스트) (소스)
- object-fit-contain-png-002p.html (실시간 테스트) (소스)
- object-fit-contain-svg-001e.html (실시간 테스트) (소스)
- object-fit-contain-svg-001i.html (실시간 테스트) (소스)
- object-fit-contain-svg-001o.html (실시간 테스트) (소스)
- object-fit-contain-svg-001p.html (실시간 테스트) (소스)
- object-fit-contain-svg-002e.html (실시간 테스트) (소스)
- object-fit-contain-svg-002i.html (실시간 테스트) (소스)
- object-fit-contain-svg-002o.html (실시간 테스트) (소스)
- object-fit-contain-svg-002p.html (실시간 테스트) (소스)
- object-fit-contain-svg-003e.html (실시간 테스트) (소스)
- object-fit-contain-svg-003i.html (실시간 테스트) (소스)
- object-fit-contain-svg-003o.html (실시간 테스트) (소스)
- object-fit-contain-svg-003p.html (실시간 테스트) (소스)
- object-fit-contain-svg-004e.html (실시간 테스트) (소스)
- object-fit-contain-svg-004i.html (실시간 테스트) (소스)
- object-fit-contain-svg-004o.html (실시간 테스트) (소스)
- object-fit-contain-svg-004p.html (실시간 테스트) (소스)
- object-fit-contain-svg-005e.html (실시간 테스트) (소스)
- object-fit-contain-svg-005i.html (실시간 테스트) (소스)
- object-fit-contain-svg-005o.html (실시간 테스트) (소스)
- object-fit-contain-svg-005p.html (실시간 테스트) (소스)
- object-fit-contain-svg-006e.html (실시간 테스트) (소스)
- object-fit-contain-svg-006i.html (실시간 테스트) (소스)
- object-fit-contain-svg-006o.html (실시간 테스트) (소스)
- object-fit-contain-svg-006p.html (실시간 테스트) (소스)
- object-fit-cover-png-001c.html (실시간 테스트) (소스)
- object-fit-cover-png-001e.html (실시간 테스트) (소스)
- object-fit-cover-png-001i.html (실시간 테스트) (소스)
- object-fit-cover-png-001o.html (실시간 테스트) (소스)
- object-fit-cover-png-001p.html (실시간 테스트) (소스)
- object-fit-cover-png-002c.html (실시간 테스트) (소스)
- object-fit-cover-png-002e.html (실시간 테스트) (소스)
- object-fit-cover-png-002i.html (실시간 테스트) (소스)
- object-fit-cover-png-002o.html (실시간 테스트) (소스)
- object-fit-cover-png-002p.html (실시간 테스트) (소스)
- object-fit-cover-svg-001e.html (실시간 테스트) (소스)
- object-fit-cover-svg-001i.html (실시간 테스트) (소스)
- object-fit-cover-svg-001o.html (실시간 테스트) (소스)
- object-fit-cover-svg-001p.html (실시간 테스트) (소스)
- object-fit-cover-svg-002e.html (실시간 테스트) (소스)
- object-fit-cover-svg-002i.html (실시간 테스트) (소스)
- object-fit-cover-svg-002o.html (실시간 테스트) (소스)
- object-fit-cover-svg-002p.html (실시간 테스트) (소스)
- object-fit-cover-svg-003e.html (실시간 테스트) (소스)
- object-fit-cover-svg-003i.html (실시간 테스트) (소스)
- object-fit-cover-svg-003o.html (실시간 테스트) (소스)
- object-fit-cover-svg-003p.html (실시간 테스트) (소스)
- object-fit-cover-svg-004e.html (실시간 테스트) (소스)
- object-fit-cover-svg-004i.html (실시간 테스트) (소스)
- object-fit-cover-svg-004o.html (실시간 테스트) (소스)
- object-fit-cover-svg-004p.html (실시간 테스트) (소스)
- object-fit-cover-svg-005e.html (실시간 테스트) (소스)
- object-fit-cover-svg-005i.html (실시간 테스트) (소스)
- object-fit-cover-svg-005o.html (실시간 테스트) (소스)
- object-fit-cover-svg-005p.html (실시간 테스트) (소스)
- object-fit-cover-svg-006e.html (실시간 테스트) (소스)
- object-fit-cover-svg-006i.html (실시간 테스트) (소스)
- object-fit-cover-svg-006o.html (실시간 테스트) (소스)
- object-fit-cover-svg-006p.html (실시간 테스트) (소스)
- object-fit-dyn-aspect-ratio-001.html (실시간 테스트) (소스)
- object-fit-dyn-aspect-ratio-002.html (실시간 테스트) (소스)
- object-fit-fill-png-001c.html (실시간 테스트) (소스)
- object-fit-fill-png-001e.html (실시간 테스트) (소스)
- object-fit-fill-png-001i.html (실시간 테스트) (소스)
- object-fit-fill-png-001o.html (실시간 테스트) (소스)
- object-fit-fill-png-001p.html (실시간 테스트) (소스)
- object-fit-fill-png-002c.html (실시간 테스트) (소스)
- object-fit-fill-png-002e.html (실시간 테스트) (소스)
- object-fit-fill-png-002i.html (실시간 테스트) (소스)
- object-fit-fill-png-002o.html (실시간 테스트) (소스)
- object-fit-fill-png-002p.html (실시간 테스트) (소스)
- object-fit-fill-svg-001e.html (실시간 테스트) (소스)
- object-fit-fill-svg-001i.html (실시간 테스트) (소스)
- object-fit-fill-svg-001o.html (실시간 테스트) (소스)
- object-fit-fill-svg-001p.html (실시간 테스트) (소스)
- object-fit-fill-svg-002e.html (실시간 테스트) (소스)
- object-fit-fill-svg-002i.html (실시간 테스트) (소스)
- object-fit-fill-svg-002o.html (실시간 테스트) (소스)
- object-fit-fill-svg-002p.html (실시간 테스트) (소스)
- object-fit-fill-svg-003e.html (실시간 테스트) (소스)
- object-fit-fill-svg-003i.html (실시간 테스트) (소스)
- object-fit-fill-svg-003o.html (실시간 테스트) (소스)
- object-fit-fill-svg-003p.html (실시간 테스트) (소스)
- object-fit-fill-svg-004e.html (실시간 테스트) (소스)
- object-fit-fill-svg-004i.html (실시간 테스트) (소스)
- object-fit-fill-svg-004o.html (실시간 테스트) (소스)
- object-fit-fill-svg-004p.html (실시간 테스트) (소스)
- object-fit-fill-svg-005e.html (실시간 테스트) (소스)
- object-fit-fill-svg-005i.html (실시간 테스트) (소스)
- object-fit-fill-svg-005o.html (실시간 테스트) (소스)
- object-fit-fill-svg-005p.html (실시간 테스트) (소스)
- object-fit-fill-svg-006e.html (실시간 테스트) (소스)
- object-fit-fill-svg-006i.html (실시간 테스트) (소스)
- object-fit-fill-svg-006o.html (실시간 테스트) (소스)
- object-fit-fill-svg-006p.html (실시간 테스트) (소스)
- object-fit-none-png-001c.html (실시간 테스트) (소스)
- object-fit-none-png-001e.html (실시간 테스트) (소스)
- object-fit-none-png-001i.html (실시간 테스트) (소스)
- object-fit-none-png-001o.html (실시간 테스트) (소스)
- object-fit-none-png-001p.html (실시간 테스트) (소스)
- object-fit-none-png-002c.html (실시간 테스트) (소스)
- object-fit-none-png-002e.html (실시간 테스트) (소스)
- object-fit-none-png-002i.html (실시간 테스트) (소스)
- object-fit-none-png-002o.html (실시간 테스트) (소스)
- object-fit-none-png-002p.html (실시간 테스트) (소스)
- object-fit-none-svg-001e.html (실시간 테스트) (소스)
- object-fit-none-svg-001i.html (실시간 테스트) (소스)
- object-fit-none-svg-001o.html (실시간 테스트) (소스)
- object-fit-none-svg-001p.html (실시간 테스트) (소스)
- object-fit-none-svg-002e.html (실시간 테스트) (소스)
- object-fit-none-svg-002i.html (실시간 테스트) (소스)
- object-fit-none-svg-002o.html (실시간 테스트) (소스)
- object-fit-none-svg-002p.html (실시간 테스트) (소스)
- object-fit-none-svg-003e.html (실시간 테스트) (소스)
- object-fit-none-svg-003i.html (실시간 테스트) (소스)
- object-fit-none-svg-003o.html (실시간 테스트) (소스)
- object-fit-none-svg-003p.html (실시간 테스트) (소스)
- object-fit-none-svg-004e.html (실시간 테스트) (소스)
- object-fit-none-svg-004i.html (실시간 테스트) (소스)
- object-fit-none-svg-004o.html (실시간 테스트) (소스)
- object-fit-none-svg-004p.html (실시간 테스트) (소스)
- object-fit-none-svg-005e.html (실시간 테스트) (소스)
- object-fit-none-svg-005i.html (실시간 테스트) (소스)
- object-fit-none-svg-005o.html (실시간 테스트) (소스)
- object-fit-none-svg-005p.html (실시간 테스트) (소스)
- object-fit-none-svg-006e.html (실시간 테스트) (소스)
- object-fit-none-svg-006i.html (실시간 테스트) (소스)
- object-fit-none-svg-006o.html (실시간 테스트) (소스)
- object-fit-none-svg-006p.html (실시간 테스트) (소스)
- object-fit-scale-down-png-001c.html (실시간 테스트) (소스)
- object-fit-scale-down-png-001e.html (실시간 테스트) (소스)
- object-fit-scale-down-png-001i.html (실시간 테스트) (소스)
- object-fit-scale-down-png-001o.html (실시간 테스트) (소스)
- object-fit-scale-down-png-001p.html (실시간 테스트) (소스)
- object-fit-scale-down-png-002c.html (실시간 테스트) (소스)
- object-fit-scale-down-png-002e.html (실시간 테스트) (소스)
- object-fit-scale-down-png-002i.html (실시간 테스트) (소스)
- object-fit-scale-down-png-002o.html (실시간 테스트) (소스)
- object-fit-scale-down-png-002p.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-001e.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-001i.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-001o.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-001p.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-002e.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-002i.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-002o.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-002p.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-003e.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-003i.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-003o.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-003p.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-004e.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-004i.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-004o.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-004p.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-005e.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-005i.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-005o.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-005p.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-006e.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-006i.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-006o.html (실시간 테스트) (소스)
- object-fit-scale-down-svg-006p.html (실시간 테스트) (소스)
- object-fit-computed.html (실시간 테스트) (소스)
- object-fit-invalid.html (실시간 테스트) (소스)
- object-fit-valid.html (실시간 테스트) (소스)
콘텐츠가 대체 요소의 content box를 완전히 채우지 못하면, 채워지지 않은 공간에는 대체 요소의 배경이 표시됩니다. 대체 요소는 항상 콘텐츠를 content box에 맞게 클리핑하므로, 콘텐츠가 넘쳐 보이지 않습니다. 오브젝트를 content box에 대해 위치시키려면 object-position 속성을 참고하세요.

참고: object-fit
속성은 [SMIL10]의 fit
속성과,
preserveAspectRatio
속성의 <meetOrSlice> 파라미터([SVG11])와 유사한 의미를 가집니다.
참고: 오브젝트 크기 협상 알고리즘에 따르면,
구체 오브젝트 크기(또는 여기서는 콘텐츠 크기)는
오브젝트 자체를 직접적으로 스케일하지 않습니다 -
단지 오브젝트에 "보이는 캔버스의 크기" 정보를 전달할 뿐입니다.
그 크기에 어떻게 그릴지는 이미지 포맷에 따라 다릅니다.
특히 래스터 이미지는 항상 주어진 크기로 스케일되고,
SVG는 주어진 크기를 "SVG 뷰포트"(SVG 용어) 크기로 사용한 뒤,
루트 <svg>
요소의 여러 속성 값에 따라 그려집니다.
6. 이미지 처리
6.1. 이미지 해상도 재정의: image-resolution 속성
이미지 해상도란 단위 길이당 이미지 픽셀 수(예: 인치당 픽셀)를 의미합니다. 일부 이미지 포맷은 해상도 정보를 기록할 수 있습니다. 이 정보는 포매팅 과정에서 실제 이미지 크기를 결정하는 데 도움이 될 수 있습니다. 하지만 이 정보가 잘못된 경우도 있으므로, 그럴 땐 무시해야 합니다. 기본적으로 CSS는 한 이미지 픽셀이 CSS px 단위 1개에 해당한다고 가정합니다; 그러나 image-resolution 속성으로 다른 해상도를 사용할 수 있습니다.
이름: | image-resolution |
---|---|
값: | [ from-image || <resolution> ] && snap? |
기본값: | 1dppx |
적용 대상: | 모든 요소 |
상속 여부: | 예 |
퍼센트 값: | 해당 없음 |
계산값: | 지정된 키워드 및/또는 <resolution> (아래 snap 적용 가능) |
정규 순서: | 문법에 따름 |
애니메이션 타입: | 불연속(discrete) |
image-set() 표기법은 이미지의 자연 해상도를 변경할 수 있습니다. 이상적으로는 이 속성을 따로 지정하지 않아도 자동으로 적용되어야 할 텐데, 이를 어떻게 처리하는 게 가장 좋을까요? 초기값을 auto로 바꿔서 "CSS에서 달리 지정하지 않으면 1dppx"로 할까요? 아니면 image-resolution이 CSS의 다른 곳에서 해상도가 정해진 이미지는 영향을 주지 않는다고 할까요? 또는 image-set()은 언제나 1dppx 이미지를 만든다고 정의할까요?
image-resolution 속성은 해당 요소에서 사용되는 모든 래스터 이미지의 선호 해상도를 지정합니다. 이는 콘텐츠 이미지(예: 대체 요소, 생성된 콘텐츠)와 장식용 이미지(background-image 등) 모두에 영향을 줍니다. 이미지의 선호 해상도는 이미지의 자연 치수를 결정할 때 사용됩니다. 값의 의미는 다음과 같습니다:
- <resolution>
- 선호 해상도를 명시적으로 지정합니다. 여기서 "dot"은 한 이미지 픽셀을 의미합니다.
- from-image
-
이미지의 선호 해상도를
이미지 포맷에서 지정한 대로 사용합니다
(여기서 자연 해상도).
이미지 자체에 해상도 정보가 없으면,
명시적으로 지정된 해상도를 사용하고(있다면),
없으면 기본값 1dppx를 사용합니다.
참고: CSS Images 3 § 2.1.2 이미지 메타데이터는 사용할 수 있는 메타데이터에 일부 제한을 둡니다.
- snap
- "snap" 키워드를 지정하면, 계산된 <resolution>(있는 경우)가 한 이미지 픽셀이 정수 개의 디바이스 픽셀에 매핑되도록 가장 가까운 값으로 반올림됩니다. 해상도가 이미지에서 가져온 것이라면, 자연 해상도도 마찬가지로 조정됩니다.
SVG와 같은 벡터 포맷은 자연 해상도 개념이 없으므로, 이 속성은 벡터 이미지에는 영향을 주지 않습니다.
img.high-res{ image-resolution : 300 dpi ; }
이렇게 설정하면 300dpi로 5인치 너비로 의도된 이미지는 실제로 5인치 폭으로 표시됩니다; 설정하지 않으면, 이미지가 가로 15000픽셀이라면 CSS는 기본적으로 인치당 96픽셀로 계산하므로 약 15.6인치 폭으로 표시됩니다.
img{ image-resolution : from-image}
아래 규칙들은 모두 UA가 이미지에 기록된 해상도를 우선 사용하되, 이미지에 해상도가 없으면 기본값 1dppx 대신 300dpi로 처리합니다.
img{ image-resolution : from-image300 dpi } img{ image-resolution : 300 dpi from-image}
img{ image-resolution : 300 dpi }
반면 아래 규칙은, 화면 해상도가 96dpi일 때, 이미지를 288dpi(이미지 3픽셀당 디바이스 1픽셀)로 렌더링합니다:
img{ image-resolution : 300 dpi snap; }
snap 키워드는 해상도가 이미지에서 결정된 경우에도 사용할 수 있습니다:
img{ image-resolution : snap from-image; }
예를 들어 이미지가 300dpi로 선언되어 있다면, 위 환경에서 288dpi(3픽셀=디바이스 1픽셀)로 표시됩니다. 반면 72dpi로 선언된 이미지는 96dpi(1픽셀=디바이스 1픽셀)로 표시됩니다.
7. 보간(Interpolation)
이 절에서는 이 명세에서 새로 정의된 값 타입들 사이에서, CSS 트랜지션 및 애니메이션 등에서 사용할 때 어떻게 보간할지 설명합니다.
아래 알고리즘에서 두 값을 "보간" 또는 "전이"하라고만 하고 자세한 설명이 없는 경우, 해당 값은 Transitions 명세에서 설명한 대로 보간해야 합니다. 그 외의 경우, 알고리즘은 보간의 자세한 설명에 t라는 변수를 참조할 수 있습니다. t는 0%에서 100%까지 변하는 수치로, 트랜지션의 진행 상황을 나타내며, 트랜지션의 지속시간, 경과시간, 사용 중인 타이밍 함수 등에 따라 결정됩니다. 예를 들어, 선형 타이밍 함수와 1초 지속시간일 때, .3초가 경과하면 t는 30%가 됩니다.
7.1. <image> 보간
모든 이미지는 보간이 가능하며, 일부 특수한 이미지(일부 그라디언트 등)는 별도의 보간 규칙을 가질 수 있습니다. 일반적으로 이미지는 start image 크기에 맞게 스케일링한 뒤, end image 크기로 바뀌면서 두 이미지를 교차 페이드(cross-fade)하는 방식으로 보간됩니다.
구체적으로는,
보간의 각 시점에서 이미지는
와
같습니다.
이미지가 없는 상태로의 보간(예: "background-image: url(foo);" → "background-image: none;")에 대한 특수 처리 필요.
7.2. cross-fade() 보간
cross-fade()의 세 가지 구성요소는 독립적으로 보간됩니다. 이로 인해 중첩된 cross-fade() 표기가 생길 수 있습니다.
7.3. <gradient> 보간
이 절은 검토 및 개선이 필요합니다. 특히 linear-gradient() 처리방식이 불완전한데, 그라디언트 선의 "길이"(0%~100% 거리)를 시작~끝 위치 사이에서 명시적으로 보간하도록 하고 싶습니다. 그래야 하나의 애니메이션 동안 선이 늘어났다 줄어드는 현상이 생기지 않습니다.
그라디언트 이미지는 CSS 트랜지션 및 애니메이션에서 직접 보간할 수 있어, 한 그라디언트에서 다른 그라디언트로 부드럽게 애니메이션됩니다. 보간이 허용되는 그라디언트에는 몇 가지 제한만 있습니다:
-
시작과 끝 그라디언트 모두 같은 함수로 표현되어야 합니다. (예: linear-gradient() → linear-gradient()는 가능하지만, linear-gradient() → radial-gradient() 또는 repeating-linear-gradient()는 불가.)
-
시작과 끝 그라디언트 모두 <color-stop> 개수가 같아야 합니다. 반복 그라디언트의 경우 무한히 많은 color stop을 가진 것으로 간주하므로, 반복 그라디언트끼리는 이 조건을 항상 만족합니다.
-
두 그라디언트 모두 <length>와 <percentage> color stop을 혼합해서 사용하면 안 됩니다.
이 조건을 모두 만족하면, 아래 설명대로 보간해야 합니다. 세 번째 조건만 실패하면, 50%에서 갑작스럽게 전환해야 합니다 (미래 명세에서 별도 규정 없는 한). 첫 번째, 두 번째 조건 중 하나라도 실패하면, 일반 이미지와 마찬가지로 cross-fade()로 보간해야 합니다.
참고: 50%에서 갑작스러운 전환을 요구하는 것은 cross-fade에 의존하지 않게 하고, 향후 더 똑똑한 보간 규칙을 추가할 수 있게 하기 위함입니다.
-
시작/끝 그라디언트를 모두 명시적(explicit) 형태로 변환:
- 선형 그라디언트의 경우:
- 방사형 그라디언트의 경우:
-
-
사이즈가 두 개의 <length> 또는 <percentage>라면 이미 명시적 형태입니다.
-
그 외의 경우, 사이즈를 동등한 종료 형태가 되도록 <length> 두 개로 변환해야 합니다. <radial-shape>가 circle이면 ellipse로 바꿔야 합니다.
-
-
각 구성요소 및 color stop을 각각 독립적으로 보간합니다. 선형 그라디언트는 각도만 보간하고, 방사형 그라디언트는 중심의 수평/수직 좌표와 수평/수직 축 길이가 모두 보간 대상입니다.
-
color stop 보간 시, 시작 그라디언트의 각 color stop을 끝 그라디언트의 동일 인덱스 color stop과 매칭합니다. 반복 그라디언트는 시작/끝의 첫 번째로 지정된 color stop이 인덱스 0이 되고, 이후 color stop들은 리스트가 반복/이동되도록 인덱싱합니다. 각 쌍에 대해 위치와 색을 독립적으로 보간합니다.
7.4. stripes() 보간
그라디언트와 유사하게, 두 stripes()도 보간이 가능하여, 한 이미지에서 다른 이미지로 부드럽게 애니메이션할 수 있습니다. 보간이 허용되는 stripes()에는 몇 가지 제한이 있습니다:
-
시작과 끝 이미지 모두 <color-stripe> 개수가 같아야 합니다.
-
보간되는 두께 쌍은 타입이 같아야 하며, 즉 두 쌍 모두 <length-percentage>이거나, <flex>이어야 합니다.
두 이미지가 두 조건을 모두 만족하면 아래 규칙대로 보간합니다. 두 번째 조건만 실패하면 50%에서 갑자기 전환하며 (미래 명세에서 별도 지정 없는 한). 첫 번째 조건이 실패하면 일반 이미지와 마찬가지로 cross-fade()로 보간합니다.
참고: 50%에서의 급격한 전환은 cross-fade에 의존하지 않게 하고, 이 경우를 위한 더 똑똑한 보간 규칙을 향후 추가할 수 있게 하기 위함입니다.
-
각 구성요소 및 stripe를 각각 독립적으로 보간합니다.
-
stripe 보간 시, 시작 이미지의 각 stripe를 끝 이미지의 동일 인덱스 stripe와 매칭한 뒤, 두께와 색상을 각각 독립적으로 보간합니다.
8. 직렬화(Serialization)
이 절에서는 이 명세에서 도입한 모든 새 속성과 값 타입을 CSS Object Model [CSSOM]과 연동하기 위한 직렬화 방법을 설명합니다.
이 모듈에서 정의된 함수의 직렬화는, 각자의 문법을 따라, 문법에 나온 순서대로, 의미가 바뀌지 않는 한 생략 가능한 구성요소는 생략하며, 공백 토큰은 한 칸으로 합치고, 콤마 뒤엔 한 칸을 둡니다.
cross-fade()의 경우, 반드시 <percentage>를 직렬화에 포함해야 합니다.
Linear-Gradient ( to bottom, red0 % , yellow, black100 px )
직렬화 결과는 아래와 같아야 합니다:
linear-gradient ( rgb ( 255 , 0 , 0 ), rgb ( 255 , 255 , 0 ), rgb ( 0 , 0 , 0 ) 100 px )
부록 A: 폐지된 기능 및 별칭
구현체는 -webkit-image-set()을 image-set()의 파싱 시점 별칭으로 허용해야 합니다. (동일한 인자를 가진 유효한 값이며, 파싱 중 image-set()으로 변환됩니다. image-set()과 완전히 동일합니다.)
9. 프라이버시 관련 고찰
참고: [css-images-3]와 변경점 없음.
10. 보안 관련 고찰
참고: [css-images-3]와 변경점 없음.
11. 변경 이력
2023년 2월 17일 Working Draft 이후 변경사항
-
외부 URL로 스타일 리소스 fetch 관련 사용을 정리함 (이슈 12065, 이슈 12068, 이슈 12086, 이슈 12147)
-
cross-fade()가 1개 이상의 인자를 허용하도록 변경 (이슈 11530)
-
각도형 color stop/hint에 >zero> 허용
-
그라디언트 회전에 대해 >zero> 명시적으로 허용
-
중복 위치가 줄무늬로 작동한다는 노트 정정. stop 리스트 앞/뒤 색상 관련 노트 추가. (이슈 11381)
-
첫/마지막 stop fixup을 별도 단계로 분리하여, stop이 하나뿐인 경우 처리 방식을 명확히 함 (이슈 10092)
-
color stop 하나만 허용 (이슈 10092)
-
cross-fade()가 color-mix()와 동일한 순서가 되도록 변경 (이슈 9405)
-
stripes() 함수에 예시 이미지 추가 (PR 9749)
-
radial-gradient(circle)에 <percentage> 값 추가, radial-gradient(ellipse)에 이중 <radial-extent> 값 추가로, radial-gradient()가 circle() 및 ellipse() <basic-shape>와 일관성을 갖도록 함. (이슈 824)
-
중립색과 보간할 때 hue가 없는 경우 예시 추가 (이슈 4928)
-
CSS Color 4 hue 보간 및 누락 성분 처리 링크 명시 (이슈 4928)
-
image-set()에서 해상도/타입 생략 허용
-
기본 보간 색상 공간이 무엇인지 명확히 기술 (이슈 7947)
-
중복 반복 그라디언트 정의 수정 (이슈 8797)
-
repeating gradient 타입의 기본 문법 추가 (이슈 8775)
-
타입이 다른 stripes() 보간 처리 수정 (이슈 8614)
-
url 요청 매개변수 지원을 위한 request modifier 추가 (PR 8222)
-
image-set()에서 모든 옵션을 제거하면 무효 이미지가 된다고 명시 (이슈 8266)
2017년 4월 13일 Working Draft 이후 변경사항
-
§ 3.5 그라디언트 색상 정의의 주요 편집 개정.
-
새로운 <image-1D> 데이터 타입과 stripes() 함수를 추가함. (이슈 2532)
-
모든 그라디언트 함수에 <color-interpolation-method>를 추가함. (이슈 6094, 6667)
-
새로운 object-view-box 속성을 추가함. (이슈 7058)
-
image-set() 정의를 [css-images-3]에서 가져오고:
-
type()를 image-set()에 추가함. (이슈 656)
-
-webkit-image-set() 호환 별칭을 추가함. (이슈 6285)
-
-
cross-fade() 정의를 [css-images-3]에서 가져오고:
-
cross-fade()가 1개 이상의 인자를 받는다는 점을 명확히 함.
-
이미지뿐 아니라 색상도 혼합할 수 있도록 허용.
-
새로운 함수 인자의 크기 산정과 페인팅을 자세히 정의.
-
cross-fade() 이미지 블렌딩 정의 오류를 수정.
-
계산 단순화 및 비교 계획에 대한 이슈 추가. (이슈 2852)
-
-
이미지의 보간 및 직렬화를 [css-images-3]에서 가져옴.
-
이미지 데이터 뒤에 위치한 메타데이터는 무시해야 함을 정의, CSS Images 3 § 2.1.2 이미지 메타데이터 참고. (이슈 4929)
-
이미지 로딩 정의 추가. (이슈 1984)
-
로딩 이미지 정의를 [css-images-3]에서 복사.
-
로딩 및 에러 처리를 image() 동작에 통합.
-
UA가 새 이미지를 불러오는 동안 기존 이미지를 계속 렌더할 수 있도록 명시.
-
§ 2.3 외부 이미지 패칭를 올바르게 정의함. (이슈 562, PR 6715)
-
-
<angle> 값에서 단위 없는 0을 conic-gradient()에 허용함. (이슈 1162, 변경)
-
scale-down을 object-fit의 다른 값과 조합 가능하도록 함. (이슈 1578)
-
누락된 <element()>를 <image> 타입에 추가. (이슈 5170)
-
elementSources
IDL 정의 수정. -
color stop 위치를 필수로 요구하던 문법 오류 수정. (이슈 1334)
-
속성 정의 테이블을 다음과 같이 업데이트:
-
여러 모듈에서 “Computed Value”와 “Animation Type” 라인을 정렬, 용어 강화, 오류 수정.
-
필요시 CSS 괄호 범위 표기법 사용.
-
“Media” 라인을 삭제.
-
-
“intrinsic dimensions”을 natural dimensions로 이름 변경 (다른 intrinsic size와 혼동 방지). (이슈 4961)
-
<image>의 계산값 정의를 [css-images-3]에서 가져옴. (이슈 4042)
-
그라디언트에서 디더링을 명시적으로 허용. (이슈 4793)
-
기타 마크업 수정, 속성 문법/인라인 이슈/맞춤법/예제/사소한 편집 개선 등.
-
모듈 제목 단축.
2012년 9월 11일 Working Draft 이후 변경사항
-
색상 보간 힌트 추가
-
그라디언트 컬러 스톱의 두 위치 문법 추가
-
원뿔형 그라디언트에 시작 각도 추가
-
이제 color stop의 위치가 색상 앞에 올 수 있음
-
[css-images-3]와 동일한 텍스트는 참고 링크로 대체.
-
-webkit-image-set() 별칭 추가.
레벨 3 이후 변경사항
-
image() 표기법 추가 (Level 3에서 이월)
-
image-resolution 속성 추가 (Level 3에서 이월)
-
element() 표기법 추가 (Level 3에서 이월)
-
원뿔형 그라디언트 추가
-
모든 그라디언트 함수에 <color-interpolation-method> 추가