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

Extend sx props to support a shorthand for container queries instead of only media queries #36670

Closed
2 tasks done
nate-summercook opened this issue Mar 28, 2023 · 20 comments · Fixed by #41674
Closed
2 tasks done
Assignees
Labels
new feature New feature or request package: system Specific to @mui/system v6.x

Comments

@nate-summercook
Copy link
Contributor

nate-summercook commented Mar 28, 2023

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Summary 💡

Currently, there is no proper support for container queries (which admittedly is still fresh) in mui. There is a practical shorthand in the sxProps to define styles for each breakpoint, but this results in a @media query and there's no shorthand for @container queries.

Some ideas:

  1. Extend createBreakpoints.js to have an optional query param in its functions:
const defaultQuery = 'media'; // with type QueryType = 'media' | 'container';
function up(key, query = defaultQuery) {
  const value = typeof values[key] === 'number' ? values[key] : key;
  return `@${query} (min-width:${value}${unit})`;
}
...
  1. Extend breakpoints.js to understand a shorthand for container queries, i.e. containerXs or just cqxs, cqsm, cqmd...

Examples 🌈

{
  color: 'red',
  color: {
    cqsm: 'blue',
  },
}

would result in:

{
  color: 'red',
  '@container (min-width:600px)': {
    color: 'blue',
  },
}

Motivation 🔦

The newly introduced @container queries are a powerful tool that will solve lots of today's problems with responsiveness. The project I'm working on heavily uses mui and its theming capabilities and we're really looking forward to the usage of @component queries as they are already now quite broadly supported. We make use of the sx props quite a lot because often they are a nicer way to quickly adjust a component to our needs compared to styled components.
Therefore it would be nice to have a way to generate @container queries with a shorthand in sx.

@nate-summercook nate-summercook added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Mar 28, 2023
@nate-summercook
Copy link
Contributor Author

This one seems a bit related: #25189

@siriwatknp
Copy link
Member

👍 It is currently ~83%, look promising.

@siriwatknp siriwatknp added new feature New feature or request waiting for 👍 Waiting for upvotes package: system Specific to @mui/system discussion and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Mar 28, 2023
@nate-summercook
Copy link
Contributor Author

I created a pull request for this feature: #36712

@siriwatknp
Copy link
Member

siriwatknp commented Jun 13, 2023

Proposal

Requirement

  • New opt-in API because browser support is still at ~87% and not everyone needs it by default.
  • Expose from MUI System so that Material UI and Joy UI can use it.
  • The API must work with sx prop and allow developers to customize the containment name.

Usage

Expose a function called containerQuery that will attach the utilities to theme.cq, a similar experience to the theme.breakpoints (I try to avoid theme.container because we have a Container component which is a different thing).

// `containerQuery` is the new API
const { containerQuery, createTheme } from '@mui/material/styles';

const theme = containerQuery(createTheme());

const MyCard = styled('div')(({ theme }) => ({
  display: 'flex',
  flexDirection: 'column',
  [theme.cq.up(300)]: { // = @container (min-width: 300px)
    flexDirection: 'row',
  },
})

// https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries#naming_containment_contexts
const MyCard2 = styled('div')(({ theme }) => ({
  display: 'flex',
  flexDirection: 'column',
  [theme.cq.up(300, 'sidebar')]: { // = @container sidebar (min-width: 300px)
    flexDirection: 'row',
  },
})

// supports valid CSS unit
const MyCard3 = styled('div')(({ theme }) => ({
  display: 'flex',
  flexDirection: 'column',
  [theme.cq.up('40ch', 'sidebar')]: { // = @container sidebar (min-width: 40ch)
    flexDirection: 'row',
  },
})

sx prop:

import { createContainerQuery, createTheme } from '@mui/material/styles';

const theme = containerQuery(createTheme());

<Box sx={{ containerType: 'inline-size' }}>
  <Card sx={{ display: 'flex',
     flexDirection: {
       'cq@xs': 'column',
       'cq@sm': 'row', // @container (min-width: 600px) 
     }
   }}>
   
   <Card sx={{ display: 'flex',
     flexDirection: {
       'cq@0': 'column',
       'cq@300': 'row', // @container (min-width: 300px) 
     }
   }}>
   
   // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries#naming_containment_contexts
   <Card sx={{ display: 'flex',
     flexDirection: {
       'cq@0/sidebar': 'column',
       'cq@300/sidebar': 'row', // @container sidebar (min-width: 300px) 
     }
   }}>
   
   <Card sx={{ display: 'flex',
     flexDirection: {
       'cq@0/sidebar': 'column',
       'cq@40ch/sidebar': 'row', // @container sidebar (min-width: 40ch) 
     }
   }}>
</Box>

cc @brijeshb42

@saksham-sharma
Copy link

@siriwatknp this looks great, even though the cq is a bit unintuitive it makes sense since using container can cause confusion with the Container component.

Thanks to @nate-summercook for initiating this conversation and to @siriwatknp for the proposal.

@siriwatknp
Copy link
Member

Huge 👏 to @nate-summercook for bringing this topic up and the POC.

@nate-summercook
Copy link
Contributor Author

nate-summercook commented Aug 30, 2023

@siriwatknp So is this going anywhere from here? :)

@beingflo
Copy link

I would also be interested in seeing this feature in MUI 👌

@issam-seghir
Copy link

Has there been any progress made on this feature yet ?

@siriwatknp
Copy link
Member

siriwatknp commented Nov 13, 2023

I'd let @brijeshb42 review the proposal once more before marking this as good to take. @brijeshb42 Do you have any concerns about the proposal to work with zero runtime?

@nate-summercook
Copy link
Contributor Author

nate-summercook commented Nov 16, 2023

I'd let @brijeshb42 review the proposal once more before marking this as good to take. @brijeshb42 Do you have any concerns about the proposal to work with zero runtime?

regarding zero runtime: Should be similar to the already existing media queries. So it shouldn't generate additional problems ;)

@LvChengbin
Copy link

Great job, but I have some questions and suggestions here:

  1. When using container queries, I rarely use fixed breakpoints for different elements, unless it's just within a fixed page layout. But if the page layout is fixed, media queries can also do most of things which container query can do.
  2. I think you should consider to keep the usage of container queries consistent with that of media queries in material-ui. For example: the usage of hooks like useMediaQuery.

@oliviertassinari oliviertassinari changed the title Extend sx props to support a shorthand for container queries instead of only media queries. Extend sx props to support a shorthand for container queries instead of only media queries Jan 3, 2024
@siriwatknp
Copy link
Member

the usage of hooks like useMediaQuery.

We need to see the use cases where CSS alone is not enough then we can consider the hook version.

@nate-summercook
Copy link
Contributor Author

Hate to be the annoying guy constantly nagging about this feature, but it's been nearly a year and pretty much nothing happened since my initial PR. What is blocking you still from marking this good to take? My project (and apparently several others) are eagerly waiting for this feature and it seems nothing is happening for months...
Also, browser support for container queries is now at 91.47%.
If you need anything more from me, please let me know, I'm glad to help :)

@siriwatknp
Copy link
Member

We will work on v6 next week. I will try to add unstable_cq in v6 alpha.

@siriwatknp siriwatknp self-assigned this Mar 14, 2024
@siriwatknp siriwatknp added v6.x and removed discussion waiting for 👍 Waiting for upvotes labels Mar 14, 2024
@elyseholladay
Copy link

Excited to see this land!

@siriwatknp
Copy link
Member

siriwatknp commented Mar 27, 2024

@nate-summercook @elyseholladay @beingflo @issam-seghir The PR is open. Here is the summary, I decided to use similar APIs as TailwindCSS (I don't see why we need a different one):

See demo here: https://deploy-preview-41674--material-ui.netlify.app/system/getting-started/usage/#responsive-values

<Box
  sx={{
    display: 'flex',
    flexDirection: { xs: 'column', '@350': 'row' },
    bgcolor: 'background.default',
    border: '1px solid',
    borderColor: 'divider',
    borderRadius: 2,
    overflow: 'clip',
  }}
>

There is one decision to be made. Should it be opt-in or default feature?

If it is an opt-in, this is good for projects that don't need container queries (keep in mind that this feature adds a very small overhead because we need to check the key and extract it into container queries).

It will be like this:

import { cssContainerQueries } from '@mui/material/styles';

const theme = cssContainerQueries(yourTheme);

I lean toward opt-in for v6 and make it a default in v7 because once you use Pigment CSS, the overhead is gone.

@PeterTYLiu
Copy link

Is there any chance this feature will be added to v5 as well?

@siriwatknp
Copy link
Member

Is there any chance this feature will be added to v5 as well?

Sorry to say this but I don't think we will add any new feature back to v5. We are now working on v6 alpha.

@nate-summercook
Copy link
Contributor Author

nate-summercook commented Apr 11, 2024

Your solution seems like a nice way to solve this. In your code example though I assume you meant to write @xs instead of xs? Because mixing media and container queries probably doesn't make much sense...

Regarding your decision about opt-in / default feature I'm fine either way. As long as there is support for it in one way or the other, I'm a happy customer :D
Thanks for getting some movement into this topic, we're still eagerly waiting for this feature. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature or request package: system Specific to @mui/system v6.x
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants