Skip to content
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

[Grid] Container responsive queries #25189

Open
1 task done
Mistes974 opened this issue Mar 4, 2021 · 18 comments
Open
1 task done

[Grid] Container responsive queries #25189

Mistes974 opened this issue Mar 4, 2021 · 18 comments
Labels
component: Grid The React component. new feature New feature or request

Comments

@Mistes974
Copy link

Mistes974 commented Mar 4, 2021

  • I have searched the issues of this repository and believe that this is not a duplicate.

Summary 💡

Hi, I started a project with react-splitter-layout and material ui library.
I would like to find a way to create responsive components, with material ui Grid or Box component

I encounter a problem with responsive, I would like my left panel to be responsive (use of xs / md / lg) with Grid component based on the size of the container (not window size), as you can see in the example below , this is not the case. It's use the viewport size. (I know it's normal because of media queries).

Examples 🌈

Here the code sample : https://codesandbox.io/s/material-demo-i04rr?file=/demo.js (recommended to open the rendering in a new tab to see the problem)

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";
import SplitterLayout from "react-splitter-layout";

const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    padding: theme.spacing(2),
    textAlign: "center",
    color: theme.palette.text.secondary
  }
}));

export default function CenteredGrid() {
  const classes = useStyles();

  return (
    <SplitterLayout>
      <div className={classes.root}>
        <Grid container spacing={3}>
          <Grid item xs={4} md={6} lg={8}>
            <Paper className={classes.paper}>xs=3</Paper>
          </Grid>
          <Grid item xs={4} md={4} lg={2}>
            <Paper className={classes.paper}>xs=3</Paper>
          </Grid>
          <Grid item xs={4} md={2} lg={2}>
            <Paper className={classes.paper}>xs=3</Paper>
          </Grid>
        </Grid>
      </div>
      <div>Panel 2</div>
    </SplitterLayout>
  );
}

Motivation 🔦

In my project the user can open/close the right panel like a sidebar/drawer with a button located on the topbar. So, everything on the left should be responsive.(When sidebar is closed the left side == screen size) Just like on the codesandbox UI, they have a code part and a rendered part, the rendering is displayed inside an iframe and when you dragging in the middle the content adapts to different devices. I would like something similar but without using an iframe.
Actually, I'm using react-container-query, but it doesn't meet all of my needs.

@Mistes974 Mistes974 added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Mar 4, 2021
@zehawki
Copy link

zehawki commented Mar 29, 2021

Hah, I came here to report this exact issue and see its here already. Its a bit strange that the grid is not responsive to its container, and instead computes based on viewport. This are many cases where one wants to render a component (which is using grid internally) within a smaller container / box etc etc. In such cases, not having the grid resize according to its own container leads to terrible UI.

@oliviertassinari oliviertassinari added the component: Grid The React component. label Mar 29, 2021
@oliviertassinari oliviertassinari changed the title Responsive components : Container Queries [Grid] Container responsve queries Mar 29, 2021
@oliviertassinari oliviertassinari changed the title [Grid] Container responsve queries [Grid] Container responsive queries Mar 29, 2021
@oliviertassinari
Copy link
Member

oliviertassinari commented Mar 29, 2021

Interesting issue. There are, more or less two solutions track.

  1. JavaScript. In this track, It's about:
    a. Having an API to measure the size of the container: Add ResizeObserver abstraction #22519.
    b. Having an API to turn size into a breakpoint value.
    c. Having an API to resolve a set of responsive values, e.g, { xs: 1, md: 2 } to the current one based on the breakpoint. It's related to Add useBreakpointValue hook #23885.
    I think that it's worth pushing further

  2. CSS.
    a. The css grid minmax approach: https://blog.logrocket.com/flexible-layouts-without-media-queries/. For instance:

    <Box
      display="grid"
      gridTemplateColumns="repeat(auto-fill, minmax(min(10rem, 100%), 1fr))"
      gap={2}
    >
      <Item>item</Item>
      <Item>item</Item>
      <Item>item</Item>
      <Item>item</Item>
    </Box>

    https://codesandbox.io/s/material-demo-forked-c5zpk?file=/demo.js:494-767
    b. else?

@oliviertassinari oliviertassinari removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Mar 29, 2021
@briant1234
Copy link

briant1234 commented May 7, 2021

Came here to report the same issue, and I was also interested in a potential solution! I was looking for a way to pass a ref to my desired container component, as a prop or something similar. The javascript solution mentioned also seems to make sense. I am using FlexLayout in my react app, and would like to be able to have the Grid respond to each tab https://github.com/caplin/FlexLayout

@membla
Copy link

membla commented May 11, 2021

Given that Container Queries are now in Chrome Canary, and the immense utility and push for this that has been over the years I'd say this possibly (probably) would get other vendors in motion too.

I actually came here looking for a way to decouple the breakpoints from the @media css implementation by allowing function values and thus having the freedom to let the breakpoint mean just about anything (but emulating container queries would clearly be the most common use case). Correct me if I'm wrong but this is not possible today, right? @oliviertassinari

@oliviertassinari
Copy link
Member

oliviertassinari commented May 15, 2021

@membla looking at the syntax of the container query, it seems something that we could easily support. The main challenge is about the browser support. At which point should we consider the feature with enough adoption to expose an API for it?

@oliviertassinari oliviertassinari added the new feature New feature or request label May 15, 2021
@membla
Copy link

membla commented May 16, 2021

Yes, that's the question. But at least I think the scene is firmly set for it now. So should be something to be taken into consideration in future planning I reckon, I guess it also depends on what kind of integration/interoperability with the current @media query system you'd aim for.

Anyway, my particular use case at the moment for something like this was very niche, I wanted to support @media queries in essentially an entire mui app based on the dimensions of the container it was mounted into. I finally just turned to react-frame-component but that was where the idea of some option of decoupling the responsivity/breakpoints from @media queries came from. Maybe that could be a way to introduce @container queries, but now I'm just speculating and it's late. @oliviertassinari

@zehawki
Copy link

zehawki commented May 16, 2021

Given slow adoption rates, I would imagine it would be a long time before Container Queries can be relied on, or?

@oliviertassinari your demo (https://codesandbox.io/s/material-demo-forked-c5zpk?file=/demo.js:494-767) looks absolutely perfect. Doesnt that already solve the issue? I will try to implement the same and report back.

@zehawki
Copy link

zehawki commented May 16, 2021

Sorry now I'm a bit confused. The Box API (https://material-ui.com/components/box/) does not have the props you mentioned.

@oliviertassinari
Copy link
Member

@zehawki The docs of v4 !== the docs of v5.

@zehawki
Copy link

zehawki commented Nov 20, 2021

Hi @oliviertassinari is there an update to this in v5, now that's it formally out. ie is there a better way to do responsive grid?

@Mistes974
Copy link
Author

for people who want an alternative while waiting react-container-query

Modularity is the heart of component based UI. With most JavaScript modularized, CSS failed to catch up. When developing a responsive web page, we use media queries to toggle styles based on the size of the viewport. This creates problems when creating component level styles. The same component will behave differently when it is placed in different locations on a page. It seriously breaks the modularity of a component. We need components to be responsive and independent of viewport sizes.

@nassim-mes
Copy link

Intent to support container queries in chrome
https://groups.google.com/a/chromium.org/g/blink-dev/c/gwzxnTJDLJ8

@ianschmitz
Copy link
Contributor

Container queries are available in Chromium as well as Safari. No impl. in Firefox but looks like they're working on it!

https://caniuse.com/css-container-queries
https://bugzilla.mozilla.org/show_bug.cgi?id=1744221

@Mistes974
Copy link
Author

Container queries are also available for Tailwind
https://tailwindcss.com/blog/tailwindcss-v3-2#container-queries

@oliviertassinari
Copy link
Member

oliviertassinari commented Nov 20, 2022

@Mistes974 I had a quick play with the API, to see a bit how it feels like right now:

import * as React from "react";
import { styled } from "@mui/system";

const Container = styled("div")({
  display: "flex",
  flexWrap: "wrap",
  gap: 4,
  containerType: "inline-size"
});

const Item = styled("div")(({ theme }) => ({
  background: "#e4bebb",
  width: "100%",
  [theme.breakpoints.up("sm").replace("@media", "@container")]: {
    width: "calc(50% - 4px)"
  },
  [theme.breakpoints.up("md").replace("@media", "@container")]: {
    width: "calc(100% / 4 - 12px)"
  }
}));

export default function GridSimple() {
  return (
    <Container>
      {new Array(10).fill().map(() => (
        <Item>test case</Item>
      ))}
    </Container>
  );
}

https://codesandbox.io/s/pedantic-bardeen-b9ghp5?file=/src/App.js

A few ideas:

  1. We might want to add an equivalent helper to theme.breakpoints.up, e.g. theme.query.container.up("md") or to make it configurable, theme.breakpoints.up("md", { container: true }).
  2. The sx prop could benefit from a breakpoint. I'm not sure about the API. e.g. <Box sx={{ width: { xs: 0, container: true } }} />

But in any case, this is off-topic to this issue. This issue is about the Grid component.

@siriwatknp
Copy link
Member

siriwatknp commented Dec 20, 2024

I am closing this issue. To use container queries, use theme.containerQueries.up(…) directly or sx shorthand with Box component. For more details, see https://mui.com/material-ui/customization/container-queries/.

I think we should not spend effort to make the Grid works with container queries, this would make the implementation more complex especially with Pigment CSS being static CSS. New component makes more sense.

<Box sx={{ display: 'flex', gap: 2 }}>
  <Box sx={{ width: { '@sm': '50%', '@md': '33.33%' } }}></Box>
</Box>

Copy link

This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

Note

@Mistes974 How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

@oliviertassinari
Copy link
Member

This is about having this built-in in the Grid component.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: Grid The React component. new feature New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants