격자 레이아웃에서 이미지 확대하기 PlatoBlockchain Data Intelligence. 수직 검색. 일체 포함.

그리드 레이아웃에서 이미지 확대/축소

CSS 그리드 덕분에 이미지 그리드를 쉽게 만들 수 있습니다. 하지만 그리드를 멋진 일로 만들면 시간 내에 배치된 이미지는 떼어내기 까다로울 수 있습니다.

그들이 앉아 있는 행과 열 너머로 확대되고 확대되는 이미지에 멋진 호버 효과를 추가하고 싶다고 가정해 봅시다. 우린 할 수있어!

멋지죠? 코드를 확인하면 JavaScript, 복잡한 선택기 또는 심지어 매직 넘버. 그리고 이것은 우리가 탐구할 많은 예 중 하나일 뿐입니다!

그리드 구축

그리드를 생성하는 HTML 코드는 컨테이너 내의 이미지 목록만큼 간단합니다. 우리는 그 이상이 필요하지 않습니다.

<div class="gallery">
  <img>
  <img>
  <img>
  <!-- etc. -->
</div>

CSS의 경우 먼저 다음을 사용하여 그리드를 설정합니다.

.gallery {
  --s: 150px; /* controls the size */
  --g: 10px;  /* controls the gap */

  display: grid;
  gap: var(--g);
  width: calc(3*var(--s) + 2*var(--g)); /* 3 times the size plus 2 times the gap */
  aspect-ratio: 1;
  grid-template-columns: repeat(3, auto);
}

즉, 두 개의 변수가 있습니다. 하나는 이미지 크기를 제어하고 다른 하나는 이미지 사이의 간격 크기를 설정합니다. aspect-ratio 비율을 유지하는 데 도움이됩니다.

왜 세 개의 열만 정의하고 행은 정의하지 않는지 궁금할 수 있습니다. 아니요, 행을 잊지 않았습니다. 행을 명시적으로 설정할 필요가 없습니다. CSS Grid는 항목을 자동으로 배치할 수 있습니다. 암시적 행 및 열, 즉, 우리가 던진 이미지 수에 필요한 만큼의 행을 얻습니다. 대신 행을 명시적으로 정의할 수 있지만 추가해야 합니다. grid-auto-flow: column 브라우저가 필요한 열을 생성하는지 확인합니다.

다음은 두 가지 경우를 설명하는 예입니다. 차이점은 하나는 row 다른 방향으로 column 방향입니다.

체크 아웃 내가 쓴 이 다른 글 암시적 그리드 및 자동 배치 알고리즘에 대한 자세한 내용은

이제 그리드가 있으므로 이미지 스타일을 지정할 차례입니다.

.gallery > img {
  width: 0;
  height: 0;
  min-height: 100%;
  min-width: 100%;
  object-fit: cover;
}

우리가 만들고 있는 호버 효과는 이 CSS에 의존합니다. 너비와 높이가 둘 다 없지만 최소 너비와 높이가 100%인 이미지를 만드는 것이 이상하게 보일 수 있습니다. 그러나 우리가 달성하려는 것에 대해 꽤 깔끔한 속임수라는 것을 알게 될 것입니다.

여기서 내가 하고 있는 것은 브라우저에 이미지가 0 너비와 높이뿐만 아니라 최소 높이도 다음과 같아야 합니다. 100%…하지만 100% 어떤? 백분율을 사용하는 경우 값은 다른 것에 비해. 이 경우 이미지는 그리드 셀 그리고 우리는 무엇이 무엇인지 알기 위해 그 크기를 알아야 합니다. 100% 에 상대적입니다.

브라우저는 먼저 무시합니다 min-height: 100% 그리드 셀의 크기를 계산하지만 height: 0 그것의 계산에서. 즉, 이미지는 기술적으로 물리적 크기가 없기 때문에 그리드 셀의 크기에 기여하지 않습니다. 이렇게 하면 그리드의 크기를 기반으로 하는 XNUMX개의 동일한 열과 행이 생성됩니다. .gallery의 폭과 aspect-ratio). 각 그리드 셀의 높이는 변수에 불과합니다. --s 우리는 정의했습니다 (너비와 동일).

그리드 레이아웃에서 이미지 확대/축소

이제 그리드 셀의 크기가 있으므로 브라우저는 이를 다음과 함께 사용할 것입니다. min-height: 100% (그리고 min-width: 100%) 이미지가 각 그리드 셀의 공간을 완전히 채우도록 합니다. 모든 것이 약간 혼란스러워 보일 수 있지만 주요 아이디어는 그리드가 이미지의 크기를 정의하는지 확인하는 것입니다. 이미지가 그리드의 크기를 정의하는 것을 원하지 않으며 호버 효과를 추가하면 그 이유를 이해할 수 있습니다.

호버 효과 만들기

우리가 해야 할 일은 이미지가 떠 있을 때 이미지의 크기를 늘리는 것입니다. 이미지의 widthheight on :hover:

.gallery {
  --f: 1.5; /* controls the scale factor */
}

.gallery img:hover{
  width:  calc(var(--s) * var(--f));
  height: calc(var(--s) * var(--f));
}

새 맞춤 변수를 추가했는데 --f, 호버의 크기를 제어하기 위한 배율 인수로 믹스에. 크기 변수를 곱하는 방법에 주목하십시오. --s, 새 이미지 크기를 계산합니다.

그런데 이미지 크기가 0이어야 한다고 하셨는데요. 무슨 일이죠? 나는 길을 잃었다…

내가 말한 것은 여전히 ​​사실이지만 호버링 된 이미지에 대해서는 예외를 만들고 있습니다. 하나의 이미지만 크기가 XNUMX이 아니므로 그리드의 크기에 기여할 것이라고 브라우저에 알리고 다른 모든 이미지는 동일하게 유지합니다. 0.

격자 레이아웃에서 이미지 확대하기 PlatoBlockchain Data Intelligence. 수직 검색. 일체 포함.
그리드 레이아웃에서 이미지 확대/축소

왼쪽은 마우스를 가져간 이미지가 없는 자연스러운 상태의 그리드를 보여줍니다. 오른쪽이 보여주고 있는 것입니다. 모든 이미지에 물리적 차원이 없기 때문에 왼쪽의 모든 그리드 셀은 크기가 동일합니다.

오른쪽에는 첫 번째 행의 두 번째 이미지가 마우스로 가리키며 그리드 셀의 크기에 영향을 미치는 치수를 제공합니다. 브라우저는 호버에서 특정 그리드 셀을 더 크게 만들어 전체 크기에 기여합니다. 그리고 전체 그리드의 크기가 설정되어 있기 때문에(고정 width 를 시청하여 이에 대해 더 많은 정보를 얻을 수 있습니다. .gallery), 다른 그리드 셀은 .gallery의 전체 크기는 재치 있습니다.

이것이 우리의 확대/축소 효과입니다! 하나의 이미지만 크기를 늘리면 전체 그리드 구성에 영향을 미치며 이전에 그리드가 이미지의 크기를 정의하여 각 이미지가 그리드 셀 내부에서 늘어나 모든 공간을 채우도록 한다고 말했습니다.

여기에 터치를 추가합니다. transition 사용 object-fit 이미지 왜곡을 피하기 위해 환상은 완벽합니다!

트릭의 논리가 이해하기 쉽지 않다는 것을 알고 있습니다. 완전히 이해하지 못하더라도 걱정하지 마십시오. 가장 중요한 것은 사용된 코드의 구조와 더 많은 변형을 얻기 위해 수정하는 방법을 이해하는 것입니다. 그것이 우리가 다음에 할 일입니다!

더 많은 이미지 추가

주요 요령을 설명하기 위해 3×3 그리드를 만들었지만 여기서 멈출 필요가 없다고 짐작하셨을 것입니다. 열과 행의 수를 변수로 만들고 원하는 만큼 이미지를 추가할 수 있습니다.

.gallery {
  --n: 3; /* number of rows*/
  --m: 4; /* number of columns */
  --s: 150px; /* control the size */
  --g: 10px;  /* control the gap */
  --f: 1.5;   /* control the scale factor */

  display: grid;
  gap: var(--g);
  width:  calc(var(--m)*var(--s) + (var(--m) - 1)*var(--g));
  height: calc(var(--n)*var(--s) + (var(--n) - 1)*var(--g));
  grid-template-columns: repeat(var(--m),auto);
}

행과 열의 수에 대한 두 가지 새로운 변수가 있습니다. 그런 다음 이를 사용하여 그리드의 너비와 높이를 간단히 정의합니다. 동일 grid-template-columns 어떤 --m 변하기 쉬운. 이전과 마찬가지로 CSS Grid의 자동 배치 기능이 사용 중인 이미지 요소 수에 관계없이 작업을 수행하므로 행을 명시적으로 정의할 필요가 없습니다.

너비와 높이 값이 다른 이유는 무엇입니까? 우린 할 수있어:

.gallery {
  --n: 3; /* number of rows*/
  --m: 4; /* number of columns */
  --h: 120px; /* control the height */
  --w: 150px; /* control the width */
  --g: 10px;  /* control the gap */
  --f: 1.5;   /* control the scale factor */

  display: grid;
  gap: var(--g);
  width:  calc(var(--m)*var(--w) + (var(--m) - 1)*var(--g));
  height: calc(var(--n)*var(--h) + (var(--n) - 1)*var(--g));
  grid-template-columns: repeat(var(--m),auto);
}

.gallery img:hover{
  width:  calc(var(--w)*var(--f));
  height: calc(var(--h)*var(--f));
}

우리는 교체 --s 두 개의 변수, 하나는 너비, --w, 높이에 대한 또 다른 하나, --h. 그런 다음 그에 따라 다른 모든 것을 조정합니다.

따라서 크기와 요소 수가 고정된 그리드로 시작했지만 원하는 구성을 얻기 위해 새로운 변수 세트를 만들었습니다. 우리가 해야 할 일은 원하는 만큼 이미지를 추가하고 그에 따라 CSS 변수를 조정하는 것입니다. 조합은 무한합니다!

전체 화면 버전은 어떻습니까? 예, 그것도 가능합니다. 우리에게 필요한 것은 변수에 할당해야 하는 값을 아는 것입니다. 우리가 원한다면 N 이미지 행이 있고 그리드가 전체 화면이 되도록 하려면 먼저 높이를 해결해야 합니다. 100vh:

var(--n) * var(--h) + (var(--n) - 1) * var(--g) = 100vh

너비에 대해 동일한 논리를 사용하지만 vw 대신 vh:

var(--m) * var(--w) + (var(--m) - 1) * var(--g) = 100vw

우리는 다음을 얻기 위해 수학을 수행합니다.

--w: (100vw - (var(--m) - 1) * var(--g)) / var(--m)
--h: (100vh - (var(--n) - 1) * var(--g)) / var(--n)

끝난!

동일한 HTML이지만 그리드의 크기와 동작을 변경하는 일부 업데이트된 변수가 있습니다.

이전에 설정한 수식을 생략했습니다. .gallery'에스 widthheight 그것들을 100vw100vh, 각각. 이 수식은 동일한 결과를 제공하지만 원하는 값을 알고 있으므로 추가된 복잡성을 모두 버릴 수 있습니다.

우리는 또한 단순화 할 수 있습니다 --h--w 다음을 위해 방정식에서 간격을 제거합니다.

--h: calc(100vh / var(--n)); /* Viewport height divided by number of rows */
--w: calc(100vw / var(--m)); /* Viewport width divided by number of columns */

이렇게 하면 호버링된 이미지가 이전 예제보다 조금 더 커지지만 크기를 제어할 수 있으므로 큰 문제는 아닙니다. --f 승수로 사용하는 변수입니다.

그리고 변수가 한 곳에서 사용되기 때문에 변수를 모두 제거하여 코드를 단순화할 수 있습니다.

이 최적화는 전체 화면 예제에만 적용되고 우리가 다룬 예제에는 적용되지 않는다는 점에 유의해야 합니다. 이 예는 다른 예에서 필요한 복잡한 계산 작업 중 일부를 제거하여 코드를 더 가볍게 만들 수 있는 특별한 경우입니다.

우리는 실제로 인기 있는 확장 패널 패턴을 만드는 데 필요한 모든 것을 갖추고 있습니다.

더 깊이 파헤쳐 보자

우리의 스케일 팩터가 1? 호버링된 이미지의 크기를 다음보다 작게 정의할 수 있습니다. --h or --w 하지만 호버링하면 이미지가 더 커집니다.

초기 그리드 셀 크기는 다음과 같습니다. --w--h, 그래서 더 작은 값이 그리드 셀을 만드는 이유는 무엇입니까? 더 큰? 셀이 가져 오지 않아야합니까? 작은, 아니면 적어도 초기 크기를 유지합니까? 그리드 셀의 최종 크기는 얼마입니까?

CSS 그리드 알고리즘이 그리드 셀의 크기를 계산하는 방법을 더 깊이 파고들 필요가 있습니다. 그리고 이것은 CSS Grid의 기본값을 이해하는 것과 관련이 있습니다. 스트레치 정렬.

다음은 논리를 이해하는 예입니다.

데모의 왼쪽에서 다음과 같이 두 개의 열을 정의했습니다. auto 너비. 두 개의 동일한 열(및 두 개의 동일한 그리드 셀)이라는 직관적인 결과를 얻습니다. 그러나 데모의 오른쪽에 설정한 그리드는 다음을 사용하여 정렬을 업데이트합니다. place-content: start, 아무것도 없는 것 같습니다.

DevTools는 두 경우 모두에서 실제로 어떤 일이 일어나고 있는지 보여줍니다.

격자 레이아웃에서 이미지 확대하기 PlatoBlockchain Data Intelligence. 수직 검색. 일체 포함.
그리드 레이아웃에서 이미지 확대/축소

두 번째 그리드에는 두 개의 열이 있지만 너비가 XNUMX이므로 그리드 컨테이너의 왼쪽 상단 모서리에 축소된 두 개의 그리드 셀이 있습니다. 이것은 지원 버그이지만 그리드 정렬의 논리적 결과입니다. 다음을 사용하여 열(또는 행)의 크기를 조정할 때 auto, 콘텐츠가 크기를 결정한다는 의미이지만 비어 있습니다. div 공간을 만들 내용이 없습니다.

하지만 그때부터 stretch 기본 정렬이고 그리드 내부에 충분한 공간이 있는 경우 브라우저는 두 그리드 셀을 균등하게 늘려 해당 영역을 모두 덮습니다. 이것이 왼쪽의 그리드가 두 개의 동일한 열로 끝나는 방식입니다.

~ 사양:

특정 값의 justify-contentalign-content 트랙이 서로 떨어져 있을 수 있습니다(space-around, space-between, space-evenly) 또는 크기 조정(stretch).

여기에서 핵심인 "크기 조정"에 유의하십시오. 마지막 예에서 나는 place-content 에 대한 속기입니다 justify-contentalign-content

그리고 이것은 어딘가에 묻혀있다. 그리드 크기 조정 알고리즘 명세서:

이 단계는 자동 최대 트랙 크기 조정 기능 나머지 양수를 나누어서 명확한 여유 공간 그들 사이에 똑같이. 여유 공간이 있는 경우 명확하지 않은하지만, 그리드 컨테이너 명확한 최소 너비/높이, 대신 이 크기를 사용하여 이 단계의 여유 공간을 계산합니다.

"Equally"는 우리가 동일한 그리드 셀로 끝맺는 이유를 설명하지만 매우 중요한 "여유 공간"에 적용됩니다.

이전 예를 사용하여 다음 중 하나에 콘텐츠를 추가해 보겠습니다. divs:

사각형을 추가했습니다. 50px 영상. 다음은 예제의 각 그리드가 해당 이미지에 어떻게 반응하는지 보여줍니다.

격자 레이아웃에서 이미지 확대하기 PlatoBlockchain Data Intelligence. 수직 검색. 일체 포함.
그리드 레이아웃에서 이미지 확대/축소

첫 번째 경우에는 첫 번째 셀(빨간색)이 두 번째 셀(파란색)보다 크다는 것을 알 수 있습니다. 두 번째 경우 첫 번째 셀의 크기는 이미지의 실제 크기에 맞게 변경되지만 두 번째 셀은 치수 없이 유지됩니다. 여유 공간은 균등하게 분할되지만 첫 번째 셀에는 더 많은 콘텐츠가 포함되어 있어 더 커집니다.

다음은 여유 공간을 계산하는 수학입니다.

(grid width) - (gap) - (image width) = (free space)
200px - 5px - 50px = 145px 

열의 수인 XNUMX로 나누면 너비는 다음과 같습니다. 72.5px 각 열에 대해. 하지만 이미지의 크기를 추가하면 50px, 하나의 열을 남기는 첫 번째 열에 122.5px 그리고 두 번째는 72.5px.

동일한 논리가 이미지 그리드에 적용됩니다. 모든 이미지의 크기는 다음과 같습니다. 0 (콘텐츠 없음) 호버링된 이미지는 크기에 기여하지만 1px — 그리드 셀을 다른 셀보다 크게 만듭니다. 이러한 이유로 배율 인수는 다음보다 큰 값이 될 수 있습니다. 0 사이의 짝수 01.

그리드 셀의 최종 너비를 얻기 위해 동일한 계산을 수행하여 다음을 얻습니다.

(container width) - (sum of all gaps) - (hovered image width) = (free space)

컨테이너의 너비는 다음과 같이 정의됩니다.

var(--m)*var(--w) + (var(--m) - 1)*var(--g)

... 그리고 모든 간격은 다음과 같습니다.

(var(--m) - 1)*var(--g)

…그리고 호버링된 이미지의 경우 다음이 있습니다.

var(--w)*var(--f)

변수를 사용하여 모든 것을 계산할 수 있습니다.

var(--m)*var(--w) - var(--w)*var(--f) = var(--w)*(var(--m) - var(--f))

열 수는 다음과 같이 정의됩니다. --m , 그래서 우리는 다음을 얻기 위해 여유 공간을 균등하게 나눕니다.

var(--w)*(var(--m) - var(--f))/var(--m)

…호버링되지 않은 이미지의 크기를 알려줍니다. 호버 이미지의 경우 다음이 있습니다.

var(--w)*(var(--m) - var(--f))/var(--m) + var(--w)*var(--f)
var(--w)*((var(--m) - var(--f))/var(--m) + var(--f))

호버링된 이미지의 최종 크기를 제어하려면 위의 공식을 고려하여 원하는 정확한 크기를 얻습니다. 예를 들어 이미지를 두 배로 크게 하고 싶다면:

(var(--m) - var(--f))/var(--m) + var(--f) = 2

따라서 스케일 승수 값은 --f, 다음과 같아야 합니다.

var(--m)/(var(--m) - 1)

세 개의 열에 대해 우리는 3/2 = 1.5 호버에서 이미지를 두 배로 크게 만들고 싶었기 때문에 이것이 이 기사의 첫 번째 데모에서 사용한 스케일 팩터입니다!

동일한 논리가 높이 계산에 적용되며 둘 다 독립적으로 제어하려는 경우 호버에서 특정 너비와 높이를 갖도록 두 가지 배율 요소를 고려해야 합니다.

.gallery {
  /* same as before */
   --fw: 1.5; /* controls the scale factor for the width */
   --fh: 1.2; /* controls the scale factor for the height */

  /* same as before */
}

.gallery img:hover{
  width:  calc(var(--w)*var(--fw));
  height: calc(var(--h)*var(--fh));
}

이제 방금 다룬 수학을 사용하여 원하는 크기를 제어하면서 멋진 호버 효과로 모든 종류의 이미지 그리드를 만드는 모든 비밀을 알게 되었습니다.

최대 포장

내에서 마지막 기사, CSS 그리드의 암시적 그리드 및 자동 배치 기능을 사용하는 몇 줄의 CSS로 복잡해 보이는 그리드를 만들었습니다. 이 기사에서는 일부 CSS 그리드 크기 조정 트릭을 사용하여 호버를 확대하고 그에 따라 그리드를 조정하는 멋진 이미지 그리드를 만들었습니다. 이 모든 것이 CSS 변수를 사용하여 쉽게 조정할 수 있는 단순화된 코드입니다!

다음 기사에서는 모양을 가지고 놀겠습니다! 멋진 이미지 그리드를 얻기 위해 CSS 그리드를 마스크 및 클립 경로와 결합합니다.

타임 스탬프 :

더보기 CSS 트릭