Thu phóng hình ảnh trong bố cục lưới Thông minh dữ liệu PlatoBlockchain. Tìm kiếm dọc. Ái.

Thu phóng hình ảnh trong bố cục lưới

Tạo một lưới hình ảnh thật dễ dàng, nhờ CSS Grid. Nhưng làm cho lưới điện làm những việc lạ lùng sau khi những hình ảnh đã được đặt có thể khó kéo ra.

Giả sử bạn muốn thêm một số hiệu ứng di chuột lạ mắt vào những hình ảnh nơi chúng phát triển và thu phóng vượt ra ngoài các hàng và cột nơi chúng ngồi? Chúng ta có thể làm điều đó!

Tuyệt, phải không? Nếu bạn kiểm tra mã, bạn sẽ không tìm thấy bất kỳ JavaScript, bộ chọn phức tạp hoặc thậm chí số ma thuật. Và đây chỉ là một ví dụ trong số rất nhiều ví dụ mà chúng ta sẽ khám phá!

Xây dựng lưới

Mã HTML để tạo lưới đơn giản như một danh sách các hình ảnh trong vùng chứa. Chúng tôi không cần nhiều hơn thế.

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

Đối với CSS, trước tiên chúng ta bắt đầu bằng cách thiết lập lưới bằng cách sử dụng như sau:

.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);
}

Tóm lại, chúng ta có hai biến, một biến kiểm soát kích thước của hình ảnh và một biến đặt kích thước khoảng cách giữa các hình ảnh. aspect-ratio giúp giữ mọi thứ theo tỷ lệ.

Bạn có thể tự hỏi tại sao chúng tôi chỉ xác định ba cột nhưng không có hàng. Không, tôi không quên các hàng - chúng ta không cần đặt chúng một cách rõ ràng. CSS Grid có khả năng tự động đặt các mục trên các hàng và cột ngầm định, có nghĩa là chúng tôi nhận được nhiều hàng nếu cần cho bất kỳ số lượng hình ảnh nào chúng tôi ném vào nó. Thay vào đó, chúng tôi có thể xác định rõ ràng các hàng nhưng chúng tôi cần thêm grid-auto-flow: column để đảm bảo trình duyệt sẽ tạo các cột cần thiết cho chúng tôi.

Dưới đây là một ví dụ để minh họa cho cả hai trường hợp. Sự khác biệt là một dòng chảy trong row hướng khác trong một column hướng.

Kiểm tra bài báo khác này tôi đã viết để biết thêm về các lưới ngầm định và thuật toán sắp xếp vị trí tự động.

Bây giờ chúng ta đã có lưới của mình, đã đến lúc tạo kiểu cho các hình ảnh:

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

Hiệu ứng di chuột mà chúng tôi đang tạo dựa trên CSS này. Có thể bạn sẽ thấy lạ khi chúng tôi đang tạo ra những hình ảnh không có chiều rộng và chiều cao nhưng có chiều rộng và chiều cao tối thiểu là 100%. Nhưng bạn sẽ thấy rằng đó là một thủ thuật khá gọn gàng cho những gì chúng tôi đang cố gắng đạt được.

Những gì tôi đang làm ở đây là nói với trình duyệt rằng hình ảnh cần phải có 0 chiều rộng và chiều cao nhưng cũng cần phải có chiều cao tối thiểu bằng 100%… nhưng 100% của cái gì? Khi sử dụng tỷ lệ phần trăm, giá trị là liên quan đến một cái gì đó khác. Trong trường hợp này, hình ảnh của chúng tôi được đặt bên trong Ô lưới và chúng ta cần biết kích thước đó để biết 100% là tương đối với.

Đầu tiên trình duyệt sẽ bỏ qua min-height: 100% để tính toán kích thước của các ô lưới, nhưng nó sẽ sử dụng height: 0 trong tính toán của nó. Điều đó có nghĩa là hình ảnh của chúng ta sẽ không đóng góp vào kích thước của các ô lưới… bởi vì về mặt kỹ thuật, chúng không có kích thước vật lý. Điều này sẽ dẫn đến ba cột và hàng bằng nhau dựa trên kích thước của lưới (mà chúng tôi đã xác định trên .gallerychiều rộng và aspect-ratio). Chiều cao của mỗi ô lưới không là gì khác ngoài biến --s chúng tôi đã xác định (tương tự cho chiều rộng).

Thu phóng hình ảnh trong bố cục lưới

Bây giờ chúng ta đã có kích thước của các ô trong lưới của mình, trình duyệt sẽ sử dụng nó với min-height: 100% (Và min-width: 100%) sẽ buộc các hình ảnh lấp đầy hoàn toàn không gian của mỗi ô lưới. Toàn bộ mọi thứ có thể trông hơi khó hiểu nhưng ý tưởng chính là đảm bảo rằng lưới xác định kích thước của hình ảnh chứ không phải ngược lại. Tôi không muốn hình ảnh xác định kích thước của lưới và bạn sẽ hiểu tại sao sau khi thêm hiệu ứng di chuột.

Tạo hiệu ứng di chuột

Những gì chúng ta cần làm là tăng tỷ lệ của hình ảnh khi chúng được di chuột qua. Chúng tôi có thể làm điều đó bằng cách điều chỉnh hình ảnh 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));
}

Tôi đã thêm một biến tùy chỉnh mới, --f, kết hợp như một hệ số tỷ lệ để kiểm soát kích thước khi di chuột. Lưu ý cách tôi đang nhân biến kích thước, --s, bằng cách đó để tính toán kích thước hình ảnh mới.

Nhưng bạn nói rằng kích thước hình ảnh cần bằng 0. Chuyện gì đang xảy ra vậy? Tôi bị lạc…

Những gì tôi đã nói vẫn đúng nhưng tôi đang tạo một ngoại lệ cho hình ảnh được di chuột qua. Tôi đang nói với trình duyệt rằng chỉ một hình ảnh sẽ có kích thước không bằng XNUMX - vì vậy nó sẽ góp phần vào kích thước của lưới - trong khi tất cả những hình ảnh khác vẫn bằng 0.

Thu phóng hình ảnh trong bố cục lưới Thông minh dữ liệu PlatoBlockchain. Tìm kiếm dọc. Ái.
Thu phóng hình ảnh trong bố cục lưới

Bên trái hiển thị lưới ở trạng thái tự nhiên mà không có bất kỳ hình ảnh nào được di chuột qua, đó là những gì bên phải đang hiển thị. Tất cả các ô lưới ở phía bên trái có kích thước bằng nhau vì tất cả các hình ảnh không có kích thước vật lý.

Ở phía bên phải, hình ảnh thứ hai trong hàng đầu tiên được di chuột, điều này cung cấp cho nó các kích thước ảnh hưởng đến kích thước của ô lưới. Trình duyệt sẽ làm cho ô lưới cụ thể đó lớn hơn khi di chuột, điều này góp phần vào kích thước tổng thể. Và vì kích thước của toàn bộ lưới được đặt (vì chúng tôi đặt width trên .gallery), các ô lưới khác sẽ phản hồi một cách hợp lý bằng cách trở nên nhỏ hơn để giữ .gallerykích thước tổng thể nguyên vẹn.

Đó là hiệu ứng thu phóng của chúng tôi đang hoạt động! Bằng cách tăng kích thước của chỉ một hình ảnh, chúng tôi ảnh hưởng đến toàn bộ cấu hình lưới và chúng tôi đã nói trước đó rằng lưới xác định kích thước của các hình ảnh để mỗi hình ảnh trải dài bên trong ô lưới của nó để lấp đầy tất cả không gian.

Đối với điều này, chúng tôi thêm một liên hệ transition Và sử dụng object-fit để tránh biến dạng hình ảnh và ảo giác là hoàn hảo!

Tôi biết rằng logic đằng sau thủ thuật này không dễ nắm bắt. Đừng lo lắng nếu bạn không hiểu đầy đủ về nó. Điều quan trọng nhất là hiểu cấu trúc của mã được sử dụng và cách sửa đổi nó để có nhiều biến thể hơn. Đó là những gì chúng tôi sẽ làm tiếp theo!

Thêm nhiều hình ảnh

Chúng tôi đã tạo một lưới 3 × 3 để giải thích thủ thuật chính, nhưng bạn có thể đoán rằng chúng tôi không cần phải dừng lại ở đó. Chúng ta có thể tạo biến số cột và hàng và thêm bao nhiêu hình ảnh tùy thích.

.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);
}

Chúng tôi có hai biến mới cho số hàng và cột. Sau đó, chúng tôi chỉ cần xác định chiều rộng và chiều cao của lưới bằng cách sử dụng chúng. Giống với grid-template-columns cái nào sử dụng --m Biến đổi. Và cũng giống như trước đây, chúng ta không cần phải xác định rõ ràng các hàng vì tính năng tự động sắp xếp của CSS Grid sẽ thực hiện công việc cho chúng ta bất kể chúng ta đang sử dụng bao nhiêu phần tử hình ảnh.

Tại sao không phải là các giá trị khác nhau cho chiều rộng và chiều cao? Chúng ta có thể làm điều đó:

.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));
}

Chúng tôi thay thế --s với hai biến, một cho chiều rộng, --wvà một cái khác cho chiều cao, --h. Sau đó, chúng tôi điều chỉnh mọi thứ khác cho phù hợp.

Vì vậy, chúng tôi bắt đầu với một lưới có kích thước và số lượng phần tử cố định, nhưng sau đó chúng tôi tạo một tập hợp các biến mới để có được bất kỳ cấu hình nào chúng tôi muốn. Tất cả những gì chúng ta phải làm là thêm bao nhiêu hình ảnh tùy thích và điều chỉnh các biến CSS cho phù hợp. Sự kết hợp là vô hạn!

Đối với phiên bản toàn màn hình thì sao? Vâng, điều đó cũng có thể. Tất cả những gì chúng ta cần là biết những giá trị nào chúng ta cần gán cho các biến của mình. Nếu chúng tôi muốn N hàng hình ảnh và chúng tôi muốn lưới của chúng tôi ở chế độ toàn màn hình, trước tiên chúng tôi cần giải quyết chiều cao của 100vh:

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

Cùng một logic cho chiều rộng, nhưng sử dụng vw thay vì vh:

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

Chúng tôi thực hiện phép toán để nhận được:

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

Làm xong!

Đó là cùng một HTML chính xác nhưng với một số biến được cập nhật thay đổi kích thước và hành vi của lưới.

Lưu ý rằng tôi đã bỏ qua công thức mà chúng tôi đã đặt trước đó trên .gallery'S widthheight và thay thế chúng bằng 100vw100vh, tương ứng. Công thức sẽ cho chúng ta cùng một kết quả nhưng vì chúng ta biết mình muốn giá trị nào, nên chúng ta có thể loại bỏ tất cả sự phức tạp tăng thêm đó.

Chúng tôi cũng có thể đơn giản hóa --h--w bằng cách loại bỏ khoảng cách khỏi phương trình có lợi cho điều này:

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

Điều này sẽ làm cho hình ảnh được di chuột phát triển hơn một chút so với ví dụ trước, nhưng nó không phải là vấn đề lớn vì chúng ta có thể kiểm soát quy mô với --f biến chúng tôi đang sử dụng làm hệ số nhân.

Và vì các biến được sử dụng ở một nơi nên chúng tôi vẫn có thể đơn giản hóa mã bằng cách xóa chúng hoàn toàn:

Điều quan trọng cần lưu ý là tối ưu hóa này chỉ áp dụng cho ví dụ toàn màn hình chứ không áp dụng cho các ví dụ mà chúng tôi đã đề cập. Ví dụ này là một trường hợp cụ thể mà chúng ta có thể làm cho mã nhẹ hơn bằng cách loại bỏ một số công việc tính toán phức tạp mà chúng ta cần trong các ví dụ khác.

Chúng tôi thực sự có mọi thứ chúng tôi cần để tạo ra mô hình phổ biến của các tấm mở rộng:

Hãy tìm hiểu sâu hơn nữa

Bạn có nhận thấy rằng hệ số quy mô của chúng tôi có thể nhỏ hơn 1? Chúng tôi có thể xác định kích thước của hình ảnh được di chuột nhỏ hơn --h or --w nhưng hình ảnh trở nên lớn hơn khi di chuột.

Kích thước ô lưới ban đầu bằng --w--h, vậy tại sao các giá trị nhỏ hơn lại làm cho ô lưới lớn hơn? Tế bào không nên nhận nhỏ hơn, hoặc ít nhất là duy trì kích thước ban đầu của nó? Và kích thước cuối cùng của ô lưới là bao nhiêu?

Chúng ta cần tìm hiểu sâu hơn về cách thuật toán CSS Grid tính toán kích thước của các ô lưới. Và điều này liên quan đến việc hiểu mặc định của CSS Grid căng thẳng hàng.

Đây là một ví dụ để hiểu logic.

Ở phía bên trái của bản trình diễn, tôi đã xác định một cột hai cột với auto bề rộng. Chúng tôi nhận được kết quả trực quan: hai cột bằng nhau (và hai ô lưới bằng nhau). Nhưng lưới tôi thiết lập ở phía bên phải của bản trình diễn, nơi tôi đang cập nhật căn chỉnh bằng cách sử dụng place-content: start, dường như không có gì.

DevTools giúp cho chúng ta thấy điều gì đang thực sự xảy ra trong cả hai trường hợp:

Thu phóng hình ảnh trong bố cục lưới Thông minh dữ liệu PlatoBlockchain. Tìm kiếm dọc. Ái.
Thu phóng hình ảnh trong bố cục lưới

Trong lưới thứ hai, chúng tôi có hai cột, nhưng chiều rộng của chúng bằng XNUMX, vì vậy chúng tôi nhận được hai ô lưới được thu gọn ở góc trên cùng bên trái của vùng chứa lưới. Đây là không một lỗi nhưng là kết quả hợp lý của sự liên kết của lưới. Khi chúng tôi định kích thước một cột (hoặc hàng) với auto, nó có nghĩa là nội dung của nó quy định kích thước của nó - nhưng chúng tôi có một sản phẩm trống div không có nội dung để nhường chỗ cho.

Nhưng kể từ stretch là căn chỉnh mặc định và chúng tôi có đủ không gian bên trong lưới của mình, trình duyệt sẽ kéo căng cả hai ô lưới bằng nhau để bao phủ tất cả khu vực đó. Đó là cách lưới bên trái tạo thành với hai cột bằng nhau.

Từ các đặc điểm kỹ thuật:

Lưu ý rằng các giá trị nhất định của justify-contentalign-content có thể khiến các bản nhạc bị cách xa nhau (space-around, space-between, space-evenly) hoặc được thay đổi kích thước (stretch).

Lưu ý "được thay đổi kích thước" là chìa khóa ở đây. Trong ví dụ cuối cùng, tôi đã sử dụng place-content đó là cách viết tắt của justify-contentalign-content

Và điều này được chôn cất ở đâu đó trong thuật toán Grid Sizing thông số kỹ thuật:

Bước này mở rộng các bản nhạc có tự động chức năng định cỡ theo dõi tối đa bằng cách chia bất kỳ số dương còn lại, xác định miễn phí không gian như nhau giữa chúng. Nếu không gian trống là vô định, nhưng thùng chứa lưới có một xác định chiều rộng / chiều cao tối thiểu, hãy sử dụng kích thước đó để tính dung lượng trống cho bước này.

“Bằng nhau” giải thích tại sao chúng ta kết hợp với các ô lưới bằng nhau, nhưng nó áp dụng cho “không gian trống”, điều này rất quan trọng.

Hãy lấy ví dụ trước và thêm nội dung vào một trong các divs:

Chúng tôi đã thêm một hình vuông 50px hình ảnh. Dưới đây là minh họa về cách mỗi lưới trong ví dụ của chúng tôi phản ứng với hình ảnh đó:

Thu phóng hình ảnh trong bố cục lưới Thông minh dữ liệu PlatoBlockchain. Tìm kiếm dọc. Ái.
Thu phóng hình ảnh trong bố cục lưới

Trong trường hợp đầu tiên, chúng ta có thể thấy rằng ô đầu tiên (màu đỏ) lớn hơn ô thứ hai (màu xanh lam). Trong trường hợp thứ hai, kích thước của ô đầu tiên thay đổi để phù hợp với kích thước vật lý của hình ảnh trong khi ô thứ hai vẫn không có kích thước. Không gian trống được chia đều, nhưng ô đầu tiên có nhiều nội dung hơn bên trong khiến nó lớn hơn.

Đây là phép toán để tìm ra không gian trống của chúng ta:

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

Chia cho hai - số cột - chúng ta có chiều rộng là 72.5px cho mỗi cột. Nhưng chúng tôi thêm kích thước của hình ảnh, 50px, đến cột đầu tiên để lại cho chúng ta một cột tại 122.5px và cái thứ hai bằng 72.5px.

Logic tương tự cũng áp dụng cho lưới hình ảnh của chúng tôi. Tất cả các hình ảnh có kích thước bằng 0 (không có nội dung) trong khi hình ảnh được di chuột lên đóng góp vào kích thước - ngay cả khi nó chỉ 1px - làm cho ô lưới của nó lớn hơn các ô khác. Vì lý do này, hệ số tỷ lệ có thể là bất kỳ giá trị nào lớn hơn 0 số thập phân chẵn giữa 01.

Để có được chiều rộng cuối cùng của các ô lưới, chúng ta thực hiện phép tính tương tự để có được kết quả sau:

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

Chiều rộng của vùng chứa được xác định bởi:

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

… Và tất cả các khoảng trống bằng:

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

… Và đối với hình ảnh được di chuột qua, chúng tôi có:

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

Chúng tôi có thể tính toán tất cả những điều đó với các biến của chúng tôi:

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

Số lượng cột được xác định bởi --m , vì vậy chúng tôi chia đều không gian trống đó để nhận được:

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

… Cung cấp cho chúng tôi kích thước của các hình ảnh không di chuột. Đối với hình ảnh được di chuột qua, chúng tôi có cái này:

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

Nếu chúng ta muốn kiểm soát kích thước cuối cùng của hình ảnh được di chuột, chúng ta xem xét công thức trên để có được kích thước chính xác mà chúng ta muốn. Ví dụ: nếu chúng tôi muốn hình ảnh lớn gấp đôi:

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

Vì vậy, giá trị của hệ số quy mô của chúng tôi, --f, cần phải bằng:

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

Đối với ba cột, chúng tôi sẽ có 3/2 = 1.5 và đó là hệ số tỷ lệ mà tôi đã sử dụng trong bản demo đầu tiên của bài viết này vì tôi muốn làm cho hình ảnh lớn gấp đôi khi di chuột!

Logic tương tự cũng áp dụng cho phép tính chiều cao và trong trường hợp chúng ta muốn kiểm soát cả hai một cách độc lập, chúng ta sẽ cần xem xét hai yếu tố tỷ lệ để đảm bảo chúng ta có chiều rộng và chiều cao cụ thể khi di chuột.

.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));
}

Bây giờ, bạn đã biết tất cả bí mật để tạo bất kỳ loại lưới hình ảnh nào với hiệu ứng di chuột thú vị trong khi vẫn có thể kiểm soát kích thước bạn muốn bằng cách sử dụng phép toán mà chúng tôi vừa đề cập.

Kết thúc

Trong tôi bài viết cuối cùng, chúng tôi đã tạo một lưới trông phức tạp với một vài dòng CSS đưa các tính năng tự động sắp xếp và lưới ngầm của CSS Grid vào sử dụng. Trong bài viết này, chúng tôi dựa vào một số thủ thuật định cỡ CSS Grid để tạo một lưới hình ảnh lạ mắt có thể phóng to khi di chuột và khiến lưới điều chỉnh cho phù hợp. Tất cả điều này với một mã đơn giản, dễ điều chỉnh bằng cách sử dụng các biến CSS!

Trong bài tiếp theo, chúng ta sẽ chơi với các hình dạng! Chúng tôi sẽ kết hợp lưới CSS với mặt nạ và đường dẫn clip để có được lưới hình ảnh lạ mắt.

Dấu thời gian:

Thêm từ Thủ thuật CSS