-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSS Grid auto height of elements? (Pinterest Layout) #19
Comments
That's not something grid is designed for. Grid is two dimensional so you are always working in both rows and columns at the same time. You can't use grid to do a "masonry" style layout like that. You could place items in that way if you had a lot of rows and managed how many each spanned, but you can't use auto-placement to get that kind of layout. |
Yeah, that layout looks very flexboxy to me, with edit of course, that changes the order of the items |
Neither flexbox or Grid can really do this masonry thing, it's a bit of a different type of layout. I'd love to come up with a solution for it, I think it fits better into flexbox type layout than grid type layout as it is a content out type of construction. However we don't have the tools currently to do it. That doesn't mean that a future level couldn't include such a feature, and that's part of why I'm collecting these use cases and seeing which things we can't do. As that's how we figure out what we need next. |
And with grid you can fake that sort of layout by spanning rows, so you can get the look of that - just not with auto-placement. I've got a bit of that going on here: http://codepen.io/rachelandrew/pen/QKwvxJ So if you know how many columns you have you can do quite a lot by spanning different numbers of rows. |
thanks a lot for the response - sad to hear we still can't do this layout with just CSS. I think CSS columns come closest to it, but the content goes top to bottom rather than left to right. I wonder if maybe a direction on CSS columns would be something worth thinking about. Thanks again! |
It does seem like CSS columns is the closest thing. In the current design of CSS-Tricks, I went for columns because I wanted to give the cards/masonry look a go, but keeping it as simple as possible. By far the biggest complaint is the up-down chronological-ness rather than left-right. Maybe someday |
I'm not sure I like However I do think this kind of layout needs to be a thing in CSS so these ideas and use cases are excellent and very useful. |
Here's a pen doing it with flexbox and only 12 lines of javascript. I know the idea was not using javascript, but I think 12 lines is a small price to pay. |
@inorganik, even tough I do like jQuery, you cannot say it's 12 line of js |
@abusedmedia I removed the jQuery, now it's 13 lines 😃 |
@programmer5000-com I think you misunderstand what this is. This is just a Q&A about grid, the Issue is closed because the original Q was answered. Linked in the thread is an issue on the CSS WG drafts if you wanted to follow that. |
yes, |
yes, different item-height allowed in same row please. |
You can check this : http://w3bits.com/css-masonry/. Works like a charm for me |
@champramentio CSS3 grid was created for static lists, like the link you gave. When new items are added into the list(like paginations), it will fail. |
Here's @inorganik's solution rewritten in modern JS (shaves off 4 lines, down to 9): const numCols = 3
const colHeights = Array(numCols).fill(0)
const container = document.getElementById('container')
Array.from(container.children).forEach((child, i) => {
const order = i % numCols
child.style.order = order
colHeights[order] += parseFloat(child.clientHeight)
})
container.style.height = Math.max(...colHeights) + 'px' Using this approach I had a lot of trouble with the // masonry/index.js
import React, { Component, createRef } from 'react'
import { Parent, Child } from './styles'
export default class Masonry extends Component {
static defaultProps = {
rowHeight: 40, // in pixels
colWidth: `17em`,
}
state = { spans: [] }
ref: createRef()
// sums up the heights of all child nodes for each grid item
sumUp = (acc, node) => acc + node.scrollHeight
computeSpans = () => {
const { rowHeight } = this.props
const spans = []
Array.from(this.ref.current.children).forEach(child => {
const childHeight = Array.from(child.children).reduce(this.sumUp, 0)
const span = Math.ceil(childHeight / rowHeight)
spans.push(span + 1)
child.style.height = span * rowHeight + `px`
})
this.setState({ spans })
}
componentDidMount() {
this.computeSpans()
window.addEventListener('resize', this.computeSpans)
}
componentWillUnmount() {
window.removeEventListener('resize', this.computeSpans)
}
render() {
return (
<Parent ref={this.ref} {...this.props}>
{this.props.children.map((child, i) => (
<Child key={i} span={this.state.spans[i]}>
{child}
</Child>
))}
</Parent>
)
}
} and the styled components: // masonry/styles.js
import styled from 'styled-components'
export const Parent = styled.div`
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(${props => props.colWidth}, 1fr)
);
grid-auto-rows: calc(${props => props.rowHeight}px - 2em);
grid-gap: 2em;
`
export const Child = styled.div`
grid-row: span ${props => props.span};
height: max-content;
` Then simply use it like so: // blog.js
import React from 'react'
import Masonry from './masonry'
import Post from './post'
const Blog = ({ posts }) => (
<Masonry>
{posts.map(post => (
<Post key={post.slug} {...post} />
))}
</Masonry>
) The above was copied here from this blog post. |
Just for reference, it's useful not only for building masonry tiles |
For anyone using Vue, this plugin takes about a minute |
column-count, but you need to sort the data. |
W3C draft: https://drafts.csswg.org/css-grid-3/ |
here's an example of this using React to manage the column rendering.
|
first- thanks so much for your work on everything grid!
I'm looking to make a layout like this.
Is this possible with grid? Rather than have the row's items stretch to the height of the largest one, I'd like the one underneath it to come up. I've looked at all your examples and I've modified this one to have one high item:
http://codepen.io/wesbos/pen/LxRaye
The text was updated successfully, but these errors were encountered: