CSS 그라디언트 및 종횡비로 반응형 이미지 효과 만들기
게시 됨: 2022-03-10object-fit
과 함께 새로 지원되는 aspect-ratio
속성은 과거의 이러한 골칫거리에 대한 해결책을 제공합니다! 추가 감각을 위한 반응형 그라디언트 이미지 효과를 만드는 것 외에도 이러한 속성을 사용하는 방법을 알아보겠습니다.미래의 이미지 효과를 준비하기 위해 상단에 큰 이미지가 있고 헤드라인과 설명이 오는 카드 구성 요소를 설정할 것입니다. 이 설정의 일반적인 문제는 이미지가 무엇인지 , 그리고 더 중요하게는 레이아웃에 대해 치수 가 무엇인지를 항상 완벽하게 제어할 수 없다는 것입니다. 미리 자르면 해결할 수 있지만 반응형 크기의 컨테이너로 인해 여전히 문제가 발생할 수 있습니다. 결과적으로 카드 행을 제시할 때 눈에 띄는 카드 콘텐츠의 위치가 고르지 않게 됩니다.
자르기 외에 다른 이전 솔루션은 인라인 img
에서 background-image
를 통해 이미지를 표시하기 위해서만 존재했던 빈 div
로 바꾸는 것이었을 수 있습니다. 나는 과거에 이 솔루션을 여러 번 구현했습니다. 이것의 장점 중 하나는 높이가 0인 요소를 사용하고 padding-bottom
값을 설정하는 종횡비에 대한 오래된 트릭을 사용한다는 것입니다. 패딩 값을 백분율로 설정하면 요소의 너비에 상대적인 최종 계산 값이 생성됩니다. 이 아이디어를 사용하여 비디오 임베딩에 대해 16:9 비율을 유지했을 수도 있습니다. 이 경우 패딩 값은 9/16 = 0.5625 * 100% = 56.26%
공식으로 찾을 수 있습니다. 그러나 우리는 추가 수학을 포함하지 않고 더 많은 유연성을 제공하며 빈 div
대신 실제 img
를 사용하여 제공되는 의미 체계를 유지할 수 있는 두 가지 최신 CSS 속성을 탐색할 것입니다.
먼저 카드의 컨테이너로 정렬되지 않은 목록을 사용하는 것을 포함하여 HTML 의미를 정의해 보겠습니다.
<ul class="card-wrapper"> <li class="card"> <img src="" alt=""> <h3>A Super Wonderful Headline</h3> <p>Lorem ipsum sit dolor amit</p> </li> <!-- additional cards --> </ul>
다음으로 .card
구성 요소에 대한 최소한의 기준 스타일 집합을 만듭니다. 카드 자체에 대한 몇 가지 기본 비주얼 스타일, 예상되는 h3
헤드라인에 대한 빠른 업데이트, 카드 이미지 스타일 지정을 시작하는 데 필수적인 스타일을 설정합니다.
.card { background-color: #fff; border-radius: 0.5rem; box-shadow: 0.05rem 0.1rem 0.3rem -0.03rem rgba(0, 0, 0, 0.45); padding-bottom: 1rem; } .card > :last-child { margin-bottom: 0; } .card h3 { margin-top: 1rem; font-size: 1.25rem; } img { border-radius: 0.5rem 0.5rem 0 0; width: 100%; } img ~ * { margin-left: 1rem; margin-right: 1rem; }
마지막 규칙은 이미지 자체가 카드의 측면과 같은 높이가 되기를 원하기 때문에 img
다음에 오는 모든 요소에 수평 여백을 추가하기 위해 일반 형제 결합 자를 사용합니다.
그리고 지금까지의 진행 상황은 다음과 같은 카드 모양으로 이어집니다.
마지막으로 CSS 그리드를 사용하여 빠른 반응형 레이아웃을 위한 .card-wrapper
스타일을 생성합니다. 이렇게 하면 기본 목록 스타일도 제거됩니다.
.card-wrapper { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(30ch, 1fr)); grid-gap: 1.5rem; }
참고 : 이 그리드 기술이 익숙하지 않은 경우 12열 그리드에 대한 최신 솔루션에 대한 내 자습서의 설명을 검토하십시오.
이것을 적용하고 유효한 소스 경로가 있는 이미지를 포함하는 모든 카드를 사용하여 .card-wrapper
스타일은 다음 레이아웃을 제공합니다.
미리 보기 이미지에서 볼 수 있듯이 이러한 기본 스타일은 다양한 자연 치수를 감안할 때 이미지를 적절하게 포함하기에 충분하지 않습니다. 이러한 이미지를 균일하고 일관되게 제한하는 방법이 필요합니다.
object-fit
으로 균일한 이미지 크기 활성화
앞서 언급했듯이 이 시나리오에서 이전에 background-image
를 통해 추가할 이미지를 변경하고 background-size: cover
를 사용하여 이미지 크기 조정을 멋지게 처리하도록 업데이트했을 수 있습니다. 또는 미리 자르기를 시도했을 수 있습니다(이미지 크기를 줄이면 성능이 향상되므로 여전히 가치 있는 목표입니다!).
이제 img
태그가 이미지의 컨테이너 역할을 할 수 있도록 하는 object-fit
속성을 사용할 수 있습니다. 그리고 cover
값도 함께 제공되어 배경 이미지 솔루션과 유사한 효과를 가져오지만 인라인 이미지 의 의미 체계를 유지하는 보너스가 있습니다. 적용하고 어떻게 작동하는지 봅시다.
이미지 컨테이너의 동작 방식에 대한 추가 지침을 위해 height
치수와 쌍을 이루어야 합니다(이미 width: 100%
를 추가했음을 기억하십시오). 그리고 max()
함수를 사용하여 주어진 컨텍스트에서 어느 것이 더 큰지에 따라 10rem
또는 30vh
를 선택할 것입니다. 이렇게 하면 더 작은 뷰포트에서 또는 사용자가 큰 확대/축소를 설정했을 때 이미지 높이가 너무 많이 축소되는 것을 방지할 수 있습니다.
img { /* ...existing styles */ object-fit: cover; height: max(10rem, 30vh); }
보너스 접근성 팁 : 항상 데스크탑에서 200% 및 400% 확대/축소로 레이아웃을 테스트해야 합니다. 현재 zoom
미디어 쿼리는 없지만 max()
와 같은 함수는 레이아웃 문제를 해결하는 데 도움이 될 수 있습니다. 이 기술이 유용한 또 다른 컨텍스트는 요소 사이의 간격입니다.
이 업데이트를 통해 우리는 확실히 개선되었으며 시각적 결과는 마치 이전 배경 이미지 기술을 사용하는 것과 같습니다.
aspect-ratio
반응적으로 일관된 이미지 크기 조정
object-fit
을 단독으로 사용할 때 한 가지 단점은 여전히 일부 차원 힌트를 설정해야 한다는 것입니다.
aspect-ratio
라고 하는 향후 속성(현재 Chromium 브라우저에서 사용 가능)은 이미지 크기를 일관되게 조정하는 능력을 향상시킬 것입니다.
이 속성을 사용하여 명시적 치수를 설정하는 대신 이미지 크기를 조정 하는 비율을 정의 할 수 있습니다. 이러한 치수가 컨테이너로서의 이미지에만 영향을 미치도록 하기 위해 object-fit
과 함께 계속 사용할 것입니다. 그렇지 않으면 이미지가 왜곡되어 나타날 수 있습니다.
다음은 완전히 업데이트된 이미지 규칙입니다.
img { border-radius: 0.5rem 0.5rem 0 0; width: 100%; object-fit: cover; aspect-ratio: 4/3; }
우리는 카드 컨텍스트에 대해 4 ⁄ 3 의 이미지 비율로 시작할 것이지만 원하는 비율을 선택할 수 있습니다. 예를 들어 정사각형의 경우 1 ⁄ 1 , 표준 비디오 삽입의 경우 16 ⁄ 9 입니다.
다음은 업데이트된 카드입니다. 비록 종횡비가 우리가 object-fit
대한 height
를 설정하여 달성한 모양과 거의 일치하기 때문에 이 특정 사례에서 시각적인 차이를 알아차리기 어려울 것입니다.
'종횡비'를 설정하면 요소가 커지거나 줄어들 때 비율이 유지되는 반면, '객체 맞춤'과 '높이'만 설정하면 컨테이너 크기가 변경됨에 따라 이미지 비율이 일정하게 유동적입니다.
"
CSS 그라디언트 및 함수로 반응형 효과 추가
자, 이제 일관된 크기의 이미지를 설정하는 방법을 알았으므로 그라디언트 효과를 추가하여 이미지를 재미있게 만들어 보겠습니다.
이 효과의 목표는 이미지가 카드 내용으로 사라지는 것처럼 보이게 하는 것입니다. 그래디언트를 추가하기 위해 이미지를 자체 컨테이너에 포장하고 싶을 수도 있지만 이미 이미지 크기 조정 작업 덕분에 기본 .card
에서 안전하게 수행하는 방법을 알아낼 수 있습니다.
첫 번째 단계는 그래디언트를 정의하는 것입니다 . 파란색에서 분홍색으로 시작하여 그라디언트 효과를 쉽게 바꿀 수 있도록 그라디언트 색상을 추가하기 위해 CSS 사용자 정의 속성을 사용할 것입니다. 그라디언트의 마지막 색상은 카드 콘텐츠 배경으로의 전환을 유지하고 "깃털이 있는" 가장자리를 만들기 위해 항상 흰색입니다.
.card { --card-gradient: #5E9AD9, #E271AD; background-image: linear-gradient( var(--card-gradient), white max(9.5rem, 27vh) ); /* ...existing styles */ }
하지만 잠깐 — 이것이 CSS max()
함수입니까? 그라데이션에서? 예, 가능합니다. 이 그라디언트를 반응적으로 효과적으로 만드는 것은 마술입니다!
그러나 스크린샷을 추가하면 그라디언트가 이미지에 영향을 미치는 것을 실제로 볼 수 없습니다. 이를 위해 mix-blend-mode
속성을 가져와야 하며 이 시나리오에서는 overlay
값을 사용합니다.
img { /* ...existing styles */ mix-blend-mode: overlay; }
mix-blend-mode
속성은 Photoshop과 같은 사진 조작 소프트웨어에서 사용할 수 있는 레이어 혼합 스타일을 적용하는 것과 유사합니다. overlay
값은 이미지의 중간 톤 이 뒤에 있는 그라디언트와 혼합 되도록 하여 다음 결과를 가져오는 효과가 있습니다.
이제 이 시점에서 이미지 크기를 조정하기 위해 aspect-ratio
값에만 의존합니다. 그리고 컨테이너의 크기를 조정하고 카드 레이아웃이 리플로우되도록 하면 이미지 높이가 변경되어 그라디언트가 흰색으로 페이드되는 위치에서 불일치가 발생합니다.
따라서 max()
함수를 사용하고 그라디언트의 값보다 약간 큰 값을 포함하는 max-height
속성 도 추가합니다. 결과 동작은 그래디언트가 (거의 항상) 이미지의 맨 아래에 올바르게 정렬된다는 것입니다.
img { /* ...existing styles */ max-height: max(10rem, 30vh); }
'최대 높이'를 추가하면 '종횡비' 동작이 변경된다는 점에 유의하는 것이 중요합니다. 항상 정확한 비율을 사용하는 대신 `max-height`의 새로운 추가 제약 조건이 주어지면 할당된 공간이 충분할 때만 사용됩니다.
"
그러나 aspect-ratio
는 여전히 object-fit
비해 이점이 있었던 것처럼 이미지 크기가 일관되게 조정되도록 계속할 것입니다. 최종 CodePen 데모에서 aspect-ratio
주석 처리하여 컨테이너 크기에 따른 차이를 확인하십시오.
우리의 원래 목표는 일관되게 반응하는 이미지 크기 를 활성화하는 것이었기 때문에 여전히 목표를 달성했습니다. 자신의 사용 사례의 경우 원하는 효과를 얻기 위해 비율과 높이 값을 조정해야 할 수도 있습니다.
대안: mix-blend-mode
및 필터 추가
overlay
를 mix-blend-mode
값으로 사용하는 것이 우리가 찾고 있던 흰색으로 변하는 효과에 대한 최선의 선택이었지만 더 극적인 효과를 위해 다른 옵션을 사용해 보겠습니다.
mix-blend-mode
값에 대한 CSS 사용자 정의 속성을 추가하고 그라디언트에 대한 색상 값도 업데이트하도록 솔루션을 업데이트할 것입니다.
.card { --card-gradient: tomato, orange; --card-blend-mode: multiply; } img { /* ...existing styles */ mix-blend-mode: var(--card-blend-mode); }
multiply
값은 중간 톤에 어둡게 하는 효과가 있지만 흰색과 검은색을 그대로 유지하므로 다음과 같이 나타납니다.
페이드를 잃어버렸고 이제 이미지 하단에 단단한 가장자리가 있지만 그라디언트의 흰색 부분은 그라디언트가 카드 내용보다 먼저 끝나도록 하는 데 여전히 중요합니다.
추가할 수 있는 수정 사항 중 하나는 filter
를 사용하는 것입니다. 특히 grayscale()
함수를 사용하여 이미지 색상을 제거하므로 그라디언트가 이미지 색상의 유일한 소스가 되도록 합니다.
img { /* ...existing styles */ filter: grayscale(100); }
grayscale(100)
값을 사용하면 이미지의 자연스러운 색상을 완전히 제거하고 흑백으로 변환합니다. 다음은 주황색 그래디언트를 multiply
때 효과의 이전 스크린샷과 비교하기 위한 업데이트입니다.
점진적 향상 aspect-ratio
사용
앞서 언급했듯이 현재 aspect-ratio
는 최신 버전의 Chromium 브라우저(Chrome 및 Edge)에서만 지원됩니다. 그러나 모든 브라우저는 object-fit
을 지원하며 height
제약 조건과 함께 다음 Safari에서 볼 수 있는 것처럼 덜 이상적이지만 여전히 수용 가능한 결과가 나타납니다.
aspect-ratio
기능이 없으면 결과적으로 궁극적으로 이미지 높이가 제한되지만 각 이미지의 자연적인 치수 는 여전히 카드 이미지 높이 사이에 약간의 차이로 이어집니다. 대신 max-height
를 추가하도록 변경하거나 max()
함수를 다시 사용하여 다양한 카드 크기에서 max-height
을 높일 수 있습니다.
그라디언트 효과 확장
그라디언트 색상 정지점을 CSS 사용자 정의 속성으로 정의했기 때문에 다양한 컨텍스트에서 변경할 준비가 되었습니다. 예를 들어 카드를 가리키거나 포커스에 자식 중 하나가 있는 경우 색상 중 하나를 더 강력하게 나타내도록 그라디언트를 변경할 수 있습니다.
먼저 다음과 같은 링크를 포함하도록 각 카드 h3
을 업데이트합니다.
<h3><a href="">A Super Wonderful Headline</a></h3>
그런 다음 사용 가능한 최신 선택기 중 하나인 :focus-within
을 사용하여 링크에 포커스가 있을 때 카드 그래디언트를 변경할 수 있습니다. 가능한 상호 작용을 추가로 다루기 위해 이것을 :hover
와 결합합니다. 그리고 max()
아이디어를 재사용하여 단일 색상을 할당하여 카드의 이미지 부분을 덮을 것입니다. 이 특정 효과의 단점은 그라디언트 정지 및 색상 변경이 안정적으로 애니메이션되지 않는다는 것입니다. 하지만 CSS Houdini 덕분에 곧 가능해집니다.
색상을 업데이트하고 새 색상 정지점을 추가하려면 이 새 규칙 내에서 --card-gradient
값을 다시 할당하기만 하면 됩니다.
.card:focus-within, .card:hover { --card-gradient: #24a9d5 max(8.5rem, 20vh); }
max()
값은 페더 가장자리를 유지하기 위해 white
에 사용되는 원래 값보다 작습니다. 동일한 값을 사용하면 white
과 만나 명확하게 직선으로 분리됩니다.
이 데모를 만들 때 원래 확대 효과를 위해 scale
이 있는 transform
을 사용하는 효과를 시도했습니다. 그러나 mix-blend-mode
가 적용되기 때문에 브라우저가 이미지를 일관되게 다시 그리지 않아 불쾌한 깜박임을 일으켰습니다. 브라우저가 CSS 전용 효과 및 애니메이션을 수행하도록 요청하는 데는 항상 절충점이 있으며, 우리가 할 수 있는 일은 매우 훌륭하지만 효과 가 성능에 미치는 영향을 확인하는 것이 항상 가장 좋습니다.
즐겁게 실험하세요!
최신 CSS는 aspect-ratio
가 가장 최근에 추가된 웹 디자인 툴킷을 업데이트하기 위한 몇 가지 멋진 도구를 제공했습니다. 그러니 계속해서 object-fit
, aspect-ratio
로 실험하고 max()
와 같은 함수를 그라디언트에 추가하여 재미있는 반응 효과를 얻으십시오! 브라우저 간(지금은!)과 다양한 뷰포트 및 컨테이너 크기에서 항목을 다시 확인하십시오.
오늘 검토한 기능과 효과가 포함된 CodePen은 다음과 같습니다.
더 찾고 계십니까? 여기 Smashing에 대한 CSS 가이드를 확인하세요 →