2017-05-11 55 views
11

Tôi đang cố gắng tạo bố cục nề sử dụng bố cục lưới css. Tất cả các mục trong lưới có biến số độ cao. Và tôi không biết những gì sẽ được. Vì vậy, tôi không thể xác định grid-row cho mỗi mục. Có thể bắt đầu mỗi mục mới ngay sau khi kết thúc cột trước đó không?Bố cục xây bằng lưới css

Mã Tôi đang cố gắng:

.wrapper { 
 
    display: grid; 
 
    grid-template-columns: repeat(auto-fill, 330px); 
 
    align-items: flex-start; 
 
    grid-column-gap: 10px; 
 
    grid-row-gap: 50px; 
 
} 
 

 
.item { 
 
    background: black; 
 
    border-radius: 5px; 
 
}
<div class="wrapper"> 
 
    <div class="item" style="height:50px"></div> 
 
    <div class="item" style="height:100px"></div> 
 
    <div class="item" style="height:30px"></div> 
 
    <div class="item" style="height:90px"></div> 
 
    <div class="item" style="height:80px"></div> 
 
    <div class="item" style="height:50px"></div> 
 
    <div class="item" style="height:70px"></div> 
 
    <div class="item" style="height:40px"></div> 
 

 
</div>

full codepen here

+0

AFAIK, CSS Lưới không làm Masonry phong cách nào hơn các phương pháp bố trí khác làm. –

+0

@Paulie_D Ok, bạn có thể nói phương pháp nào không? – user2950602

+2

Lưới CSS có thể làm Masonry tốt, nếu bạn có thể xác định chiều cao trong lưới. Nó có thể không hoàn toàn tự động nhưng nó có thể hữu ích trong nhiều trường hợp. http://stackoverflow.com/a/43903119/3597276 –

Trả lời

-2

Bạn có thể thực hiện điều này với column.

.wrapper { 
    column-gap: 10px; 
    column-count: 4; 
} 

.item { 
    display: inline-block; 
    background: #000; 
    width: 100%; 
    border-radius: 3px; 
} 

Dường như bạn đang cố gắng sử dụng một sự kết hợp của flexgrid, đó có thể là điều khó hiểu. Theo như tôi biết, flex là tương đối so với phần còn lại của các mục trên trang, nơi thiết lập một cột ảnh hưởng đến các mục rơi vào các cột đó.

updated codepen

+0

Trong khi điều này về lý thuyết có thể trả lời câu hỏi, [** nó sẽ là thích hợp hơn **] (// meta.stackoverflow.com/q/8259) để bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi –

+0

Đã chỉnh sửa để thêm giải thích/mã khác @Paulie_D –

+0

@WillThresher, điều gì khiến bạn nghĩ rằng "flex liên quan đến phần còn lại của các mục trên trang"? Quy tắc đặc biệt của Flexbox chỉ áp dụng cho hậu duệ trực tiếp của phần tử với 'display: flex'. –

0

Đây là một cách để tạo ra các layout Masonry chỉ sử dụng CSS.

*, 
 
*:before, 
 
*:after { 
 
    box-sizing: border-box !important; 
 
} 
 

 
article { 
 
    -moz-column-width: 13em; 
 
    -webkit-column-width: 13em; 
 
    -moz-column-gap: 1em; 
 
    -webkit-column-gap: 1em; 
 
} 
 

 
section { 
 
    display: inline-block; 
 
    margin: 0.25rem; 
 
    padding: 1rem; 
 
    width: 100%; 
 
    background: #efefef; 
 
} 
 

 
p { 
 
    margin: 1rem 0; 
 
} 
 

 
body { 
 
    line-height: 1.25; 
 
}
<article> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error aliquid reprehenderit expedita odio beatae est.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nobis quaerat suscipit ad.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem nihil alias amet dolores fuga totam sequi a cupiditate ipsa voluptas id facilis nobis.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem ut debitis dolorum earum expedita eveniet voluptatem quibusdam facere eos numquam commodi ad iusto laboriosam rerum aliquam.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat architecto quis tenetur fugiat veniam iste molestiae fuga labore!</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odit accusamus tempore at porro officia rerum est impedit ea ipsa tenetur. Labore libero hic error sunt laborum expedita.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima asperiores eveniet vero velit eligendi aliquid in.</p> 
 
    </section> 
 
    <section> 
 
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus dolorem maxime minima animi cum.</p> 
 
    </section> 
 
</article>

Lưu ý: tôi không thực hiện các mã, tôi thấy nó trở thành một thực hiện một số chỉnh nhỏ, mã ban đầu có thể được tìm thấy here.


Xin lưu ý rằng, như đã chỉ ra bởi Zen:

[...] các mục được đặt ra top-to-bottom, trái sang phải, trong khi những gì người ta thường mong đợi (giả định văn hóa được miễn) là từ trái sang phải, bố cục từ trên xuống dưới cùng. Đây là showstopper cho các khuyến nghị dựa trên CSS3-cột thông thường.

+6

"Vấn đề với giải pháp này là các mục được đặt ra từ đầu đến cuối, từ trái sang phải, trong khi những gì người ta thường mong đợi (giả định văn hóa được miễn) là từ trái sang phải, bố cục từ trên xuống dưới. Đây là showstopper cho các khuyến nghị dựa trên CSS3-cột thông thường. " – Zen

0

Bạn có thể đặt span giá trị cho grid-row-end động (với một chút JS, giống như một dựa trên Codepen experiment của tôi trong ví dụ dưới đây) và sử dụng các từ khóa dense cho grid-auto-placement:

const gridStyles = getComputedStyle(document.querySelector('.wrapper',null)); 
 
const rowHeight = parseInt(gridStyles.getPropertyValue('--grid-row-height')); 
 
const gap = parseInt(gridStyles.getPropertyValue('--grid-gutter'));; 
 

 
let makeGrid = function() { 
 
    let items = document.querySelectorAll('.item'); 
 
    for (let i=0, item; item = items[i]; i++) { 
 
    // take an item away from grid to measure it 
 
    item.classList.add('is-being-measured'); 
 
    let height = item.offsetHeight; 
 
    // calcylate the row span 
 
    let rowSpan = Math.ceil((height + gap)/(rowHeight + gap)); 
 
    // set the span value for grid-row-end 
 
    item.style.gridRowEnd = 'span '+rowSpan; 
 
    // return the item into the grid 
 
    item.classList.remove('is-being-measured'); 
 
    } 
 
} 
 

 
window.addEventListener('load', makeGrid); 
 
window.addEventListener('resize',() => { 
 
    clearTimeout(makeGrid.resizeTimer); 
 
    makeGrid.resizeTimer = setTimeout(makeGrid, 50); 
 
});
.wrapper { 
 
    display: grid; 
 
    grid-template-columns: repeat(auto-fill, 330px); 
 
    --grid-gutter: 10px; 
 
    grid-gap: var(--grid-gutter); 
 
    --grid-row-height: 10px; 
 
    grid-auto-rows: var(--grid-row-height); 
 
    grid-auto-flow: row dense; 
 
    position: relative; 
 
} 
 

 
.item { 
 
    background: black; 
 
    color: white; 
 
    border-radius: 5px; 
 
} 
 
.item.is-being-measured { 
 
    /* temporary styles for measuring grid items */ 
 
    position: absolute; 
 
    width: 330px; 
 
    top: 0; 
 
    left: 0; 
 
} 
 

 
.item > * { margin-left: 20px; }
<div class="wrapper"> 
 
    <div class="item"><h3>1.1</h3><p>1.2</p></div> 
 
    <div class="item"><p>2.1</p><p>2.2</p><p>2.3</p><p>2.4</p><p>2.5</p></div> 
 
    <div class="item"><h2>3.1</h2></div> 
 
    <div class="item"><h2>4.1</h2><p>4.2</p><p>4.3</p><p>4.4</p></div> 
 
    <div class="item"><p>5.1</p><p>5.2</p><p>5.3</p><p>5.4</p></div> 
 
    <div class="item"><h2>6.1</h2><p>6.2</p></div> 
 
    <div class="item"><h2>7.1</h2><p>7.2</p><p>7.3</p></div> 
 
    <div class="item"><p>8.1</p><p>8.2</p></div> 
 

 
</div>

0

Trong câu hỏi của bạn, bạn đang đặt chiều cao của từng mục riêng lẻ. Nếu bạn đang hạnh phúc để làm điều này sau đó bố trí Masonry có thể dễ dàng đạt được với lưới điện.

Thay vì đặt chiều cao cho từng mục được đặt grid-row-end để mỗi mục mở rộng một số hàng nhất định.

<div class="item" style="grid-row-end: span 5"></div> 

Chiều cao của mặt hàng đó sau đó sẽ phụ thuộc vào giá trị của grid-auto-rowsgrid-row-gap bạn đã đặt cho lưới điện.

Tôi đã thực hiện một Codepen đây: https://codepen.io/andybarefoot/pen/NaprOB

Nếu bạn không muốn cá nhân thiết lập các grid-row-end giá trị cho từng hạng mục, bạn có thể sử dụng một chút JavaScript để làm điều đó tự động. Tôi đặt một div "container" khác bên trong mỗi mục và đo chiều cao của vùng chứa này để tính toán số hàng mà mục cần span. Tôi làm điều này trên tải trang, và một lần nữa cho mỗi mục khi bất kỳ hình ảnh được nạp (như chiều cao của nội dung sẽ thay đổi). Nếu bạn kết hợp cách tiếp cận này với bố cục đáp ứng thì bạn cũng nên tính toán lại trên trang thay đổi kích thước vì chiều rộng của các cột có thể đã thay đổi và điều này sẽ ảnh hưởng đến chiều cao của nội dung.

Dưới đây là ví dụ đầy đủ của tôi với cột thay đổi kích thước đáp ứng: https://codepen.io/andybarefoot/pen/QMeZda

Nếu bạn có mục có độ rộng biến bạn vẫn có thể đạt được một hiệu ứng tương tự nhưng bao bì của lưới điện sẽ không được hoàn hảo và thứ tự mục có thể được thay đổi để tối ưu hóa việc đóng gói.

Tôi đã viết một blog trên Medium về phương pháp này trong trường hợp nó là quan tâm: Một bố trí theo phong cách Masonry sử dụng CSS Lưới

Các vấn đề liên quan