How do you use CSS grid layouts with React effectively?
Asked Answered
T

3

9

I'm currently building a Single Page Application using ReactJs and CSS grid layouts for the placement and styling of components.

However, the two technologies don't feel like they go together well: CSS grid layouts can only (easily) be applied to children elements (grid items) of the parent container. But the very nature of ReactJS means components with grand-children components and even great-grand-children are common.

As an example:

React component tree: App > ToDoList > ToDo Item > Details...

If, onClick, I want to move the 'ToDo Item' to grid-row: 1 of the 'App' component it seems the only way to do so is for ToDoList to itself be a grid of the entire App component. This then causes layout issues of other elements on the page.

Am I right in thinking these two approaches don't play well together, or is it a flaw in my understanding of the two technologies?

Tamqrah answered 7/6, 2017 at 9:47 Comment(1)
Not related to your question, but if you are not locked in yet, then you can have a look at tachyons. It is capable of providing inline media-queries based grids and is nestable.Simulacrum
F
2

You're right, subgrids were deprecated from the CSS Grid Candidate Recommendation (https://github.com/w3c/csswg-drafts/issues/958).

Hopefully they'll reappear, they seem really useful for simplifying complicated layouts. I've only found CSS grid to be useful laying out the top level of an react application or a container.

Fronton answered 4/7, 2017 at 8:29 Comment(0)
M
0

You can define a component like this which 'unwraps' the outer element of each child:

const Unwrap = ({ children, ...props}) => (
    <div {...props}>
        {children.reduce((acc, child) => acc.concat(child.children), [])}
    </div>
)

And then use it like this:

<Unwrap>
    {rows.map(renderMyRow)}
</Unwrap>

Edit: I just noticed that this actually doesn't always work but I'm too tired to figure out under what circumstances it fails.

Edit again: A better approach may be to wrap a row in a div with display set to contents as shown here: https://mcmap.net/q/343172/-how-to-make-hover-state-on-row-table-with-css-grid-layout

Matheson answered 10/11, 2018 at 22:31 Comment(0)
P
0

I definitely have seen this same issue, and even though this is a relatively old question, I think it's a really interesting one.

In my opinion, the reality is that if you are using a component-driven framework to it's full potential, you run into this issue of deeply nested components/elements. While there isn't a true 'subgrid', keep in mind that "Any Grid Area can become a grid itself, by setting display:grid and then defining the rows and columns." (https://gridbyexample.com/examples/example21/). However if you have something like this:

<div class="page-wrapper">
  <section></section>
  <section></section>
  <section>
    <div class="section-item"></div>
    <div class="section-item">
      <div class="sub-section"><div>
    </div>
  </section>
 </div>

And you want to use CSS to put .sub-section somewhere else on the grid defined on .page-wrapper that isn't something you can do just by changing css, except perhaps with some tricky absolute or fixed positioning. At the end of the day, you can really only rearrange items within their parent.

Shooting from the hip a bit, I might suggest something like having an empty component in that 'new' position that can communicate with the original 'to-do list' component, and on click, move it from one to the other.

On the broader topic, though -- I would submit that making a decision about what CSS layout option to use should be addressed at each progressive level of the page layout. Just because Grid or Flex works great (or doesn't) to layout the large sections of your particular design doesn't mean you have to (or should) be locked in to that layout for all the elements of your app. To take it one step further, within each of those sections, I believe you should evaluate your options for layout of that particular section, based on the contents and how they are organized and displayed.

For instance, if the main content of your page is a grid or masonry style layout, by all means, grid might be the best for that section, but that doesn't mean you need grid for the whole page layout...you could very likely find that you have better results using flex for the top level layout, and put your grid inside one of those sections.

As another example, if you lay out your top level page sections with grid, that grid would control where your menu is displayed, but it still probably makes a lot of sense to layout your menu items using flex within that grid section.

Lastly, to add a little broader context to the conversation, this is really just another version of the questions many developers ran into with CSS grids like Bootstrap that use floats to create columns. Sure you can nest bootstrap rows and columns to create subgrids, but in terms of getting great responsive behavior, it's a real challenge after the first or second nested layer (depending on how much patience you have and how committed you are to using only that grid system for your layout).

Teams I've worked on found pretty quickly that using bootstrap's grid for the large sections and flex for most of the internal contents of those sections was a lot easier to maintain - not to mention needing less markup. With grid also being widely supported now, I'm expecting we'll find similar efficiencies in terms of grid more frequently being used in places where floats and flex used to be the only options.

Prelate answered 10/11, 2018 at 23:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.