2017-05-11 6 views
11

Ich versuche, Mauerwerk Layout mit CSS-Raster-Layout zu erstellen. Alle Elemente im Raster haben variable Höhen. Und ich weiß nicht, welche Gegenstände sein werden. Also kann ich grid-row nicht für jedes Element definieren. Ist es möglich, jeden neuen Artikel direkt nach dem Ende der vorherigen Spalte zu starten?Mauerwerk Layout mit CSS-Gitter

-Code Ich versuche:

.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 Grid nicht tut Mauerwerk Stil mit CSS Grid mehr als anderen Layout-Methoden tun. –

+0

@Paulie_D Ok, kannst du sagen, welche Methoden? – user2950602

+2

CSS Grid kann Mauerwerk gut tun, wenn Sie die Höhen im Raster definieren können. Es ist möglicherweise nicht vollständig automatisiert, aber es kann in vielen Fällen nützlich sein. http://StackOverflow.com/a/43903119/3597276 –

Antwort

-2

Sie erreichen dies mit column.

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

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

Es sieht aus wie Sie eine Kombination aus flex und grid zu nutzen versuchten, die verwirrende Dinge gewesen sein mag. Soweit ich weiß, ist flex relativ zu den anderen Elementen auf der Seite, wobei das Setzen einer Spalte sich auf Elemente auswirkt, die in diese Spalten fallen.

updated codepen

+0

Während dies theoretisch die Frage beantworten könnte, [** wäre es vorzuziehen **] (// meta.stackoverflow.com/q/8259), hier die wesentlichen Teile der Antwort aufzunehmen und den Link als Referenz bereitzustellen. Link-Only-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. –

+0

Bearbeitet, um mehr Erklärung/Code hinzuzufügen @Paulie_D –

+0

@WillThresher, was hat Sie dazu gebracht zu denken, dass "flex relativ zu den anderen Elementen auf der Seite ist"? Spezielle Regeln von Flexbox gelten nur für direkte Nachkommen des Elements mit 'display: flex'. –

0

Dies ist eine Möglichkeit, das Mauerwerk Layout mit nur CSS zu erstellen.

*, 
 
*: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>

Hinweis: ich den Code nicht gemacht habe, fand ich es ein paar kleine Anpassung vorgenommen, der ursprüngliche Code here gefunden werden kann.


Bitte beachten Sie, dass, wie von Zen wies darauf hin:

[...] die Gegenstände gelegt top-to-bottom, von links nach rechts, während was normalerweise erwartet (kulturelle Annahmen entschuldigt) ist von links nach rechts, von oben nach unten Layout. Dies ist der Showstopper für die üblichen CSS3-Spalten-basierten Empfehlungen.

+6

"Das Problem bei dieser Lösung ist, dass die Elemente von oben nach unten und von links nach rechts angeordnet sind, während das, was normalerweise erwartet wird (kulturelle Annahmen sind entschuldigt), von links nach rechts und von oben nach unten angeordnet ist. Dies ist der Showstopper für die üblichen CSS3-Spalten-basierten Empfehlungen. " – Zen

0

Sie können span Werte für grid-row-end dynamisch festgelegt (mit ein wenig JS, wie die auf Grund meiner Codepen experiment im Beispiel unten) und verwenden Sie die dense Schlüsselwort für 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

In Ihrer Frage stellen Sie die Höhe jedes Artikels einzeln ein. Wenn Sie dies gerne tun, kann ein Mauerwerk-Layout leicht mit Raster erreicht werden.

Anstatt eine Höhe für jedes Element festzulegen grid-row-end, so dass jedes Element eine bestimmte Anzahl von Zeilen umfasst.

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

Die Höhe des Elements hängt dann von den Werten von grid-auto-rows und grid-row-gap Sie haben für das Raster festlegen.

Ich habe eine Codepen hier gemacht: https://codepen.io/andybarefoot/pen/NaprOB

Wenn Sie nicht wollen, einzeln, um den grid-row-end Wert für jedes Element, das Sie ein wenig JavaScript verwenden können sie dynamisch zu tun. Ich lege ein weiteres "Container" -Div in jedes Element und messe die Höhe dieses Containers, um zu berechnen, wie viele Zeilen das Element überspannen muss. Ich mache das beim Laden der Seite und erneut für jedes Element, wenn Bilder geladen werden (da sich die Höhe des Inhalts geändert hat). Wenn Sie diesen Ansatz mit einem reaktionsfähigen Layout kombinieren, sollten Sie auch die Seitengröße neu berechnen, da sich die Breite der Spalten möglicherweise geändert hat und sich dies auf die Höhe des Inhalts auswirkt.

Hier ist mein komplettes Beispiel mit dem feinfühligen Spalte Redimensionierung: https://codepen.io/andybarefoot/pen/QMeZda

Wenn Sie Elemente mit variabler Breite haben, können Sie immer noch eine ähnliche Wirkung erzielen, aber die Verpackung des Gitters wird nicht perfekt sein und das Element geändert werden kann um die Verpackung zu optimieren.

schrieb ich einen Blog auf Medium über diesen Ansatz, falls es von Interesse ist: Ein Layout Mauerwerk Stil