mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.96k stars 32.27k forks source link

[Container] Background Color Extending to Margin #31119

Closed aress31 closed 2 years ago

aress31 commented 2 years ago

Duplicates

Latest version

Summary 💡

I would like to see an easy and out-of-the-box way to fully set the background color of a Container component with a set width.

Examples 🌈

Could be setting a property that would change the internal working/styles of a Container:

<Container maxWidth='lg' coloredMargin>
--- Code for a Hero ---
<Container>

Motivation 🔦

So far, architecturally speaking not being able to fully set a background color to a Container due to the width limits adds a lot of complexity and useless code, e.g., `parent divs1...

Implementing this, would reduce code complexity of many projects - including mine!

PunitSoniME commented 2 years ago

reproduction of this issue in codesandbox would be more helpful

aress31 commented 2 years ago

No reproduction needed, as said when using q Container with a maxWidth, there is a left/right margin.

Try applying a backgroundColor to the Container and you will see that the color is not spanning across the whole width... That's the issue...

It seems that bootstrap is providing such feature:

This should be a must really annoying trying to find work around with parents divs just to colours my background...

PunitSoniME commented 2 years ago

there is a prop named disableGutters

add that and try again, it will remove left & right padding

<Container maxWidth="sm" style={{ backgroundColor: 'red' }} disableGutters>
     <Typography component="div" style={{ height: '100vh' }} />
</Container>
aress31 commented 2 years ago

@PunitSoniME disableGutters doesn't disable the margin therefore not relevant to this use case.

We need either an option to either swap the margin by padding so that the backgroundColor can take the full width OR add a switch that would change the internal CSS of a Container to allow it to color the full width even when setting a maxWidth.

hbjORbj commented 2 years ago

Hi. You can achieve a full-width with background color with a combination of fixed prop and sx={{ maxWidth: "100% !important", margin: 0 }}. Please check out this codesandbox.

aress31 commented 2 years ago

Thanks @hbjORbj not really a fan of using !important.

Also, in my case, my Container/content should have a maxWidth of lg whilst the backgroundColor should take up all the screen width.

I think you didn't really understand my question/request feature.

In any case, I really think that an out of the box solution would be needed for this as it is a quite common designing use case, and the lack of this feature adds a lot of complexity and workaround...

Your thoughts? 🤔

hbjORbj commented 2 years ago

the lack of this feature adds a lot of complexity and workaround...

Can you provide a codesandbox that clearly shows your struggle? You can fork this template: https://material-ui.com/r/issue-template-latest

We need to have a concrete reason before making a decision to add another API.

aress31 commented 2 years ago

Please read the above, it's not hard to understand and doesn't require a codebox...

When using a container with a maxwidth the content is centered and the box too, therefore setting a background color on this container doesn't apply to the left right margin....

What would a codebox do more?

Container -> set width with margins therefore no background color on full width...

If you insist on a codebox, here you go:

<Container maxWidth="lg" sx={{backgroundColor: "purple"}}>
---FOO---
</Container>
hbjORbj commented 2 years ago

What I mean is how exactly the lack of "not allowing you to apply background-color beyond the max-width" add a lot of complexity and workaround? This sounds like an expected behaviour to me. Before we put in the effort of implementing your request, we need to see the "complexity" that this will get rid of.

If you want to have a max-width in your Container AND also a background that covers beyond the max-width, you either need to (1) use the combination of fixed prop and sx={{ maxWidth: "100% !important", margin: 0 }} as I suggested above (codesandbox), or (2) wrap your Container component with another wrapper like Box and apply background-color to that wrapper component (codesandbox).

I think (2) is a normal thing to do, but since you asked specifically for how to implement such in Container component, I suggested (1) solution. Both solutions seem simple enough to me.

aress31 commented 2 years ago

@hbjORbj I get your point, but many frameworks and component libraries seem to easily allow expanding the background colour of a fixed width container.

Use case are multiples, for example if you want to wrap your entire page content in a container but at the same time want to apply a gradient background colour.

Anyway, this is up for discussion, and I believe that would be a nice addition that would not require too much changes to Container.

michaldudak commented 2 years ago

If I understand the issue correctly, this seems to be easy to implement in userland: https://codesandbox.io/s/stoic-sun-p8cvxf?file=/src/Demo.tsx

We can't afford to implement every feature that's easily achievable in client code. If, however, we see that there is a more widespread need for it (measured by the number of upvotes of this issue), we will consider adding the feature.

aress31 commented 2 years ago

@michaldudak thanks for this working solution. 😇

On a side note though it still adds an unnecessary HTML tag/component.

michaldudak commented 2 years ago

How would you see it implemented without an additional tag? You can't set padding: auto in CSS, so you need one element that has a background color and another nested one that restricts the width of the content. I suppose you could do some trickery with pseudoelements, but I haven't checked. Plus, I don't think it's even worth trying.

aress31 commented 2 years ago

That's what I have done with pseudo elements ai targeted all the children and set a maxWidth with a margin auto to them.

It's a quick a dirty hack but worked for my case.

Anyway, as you suggested let's keep this ticket open and see if more people would like a native solution.

oliviertassinari commented 2 years ago

@aress31 You can add a wrapping div https://github.com/mui/material-ui/issues/31119#issuecomment-1043365202. This is already as simple as it can get, from my perspective:

import * as React from "react";
import CssBaseline from "@mui/material/CssBaseline";
import Box from "@mui/material/Box";
import Container from "@mui/material/Container";

export default function FixedContainer() {
  return (
    <React.Fragment>
      <CssBaseline />
      <Box bgcolor="primary.main">
        <Container>Hello</Container>
      </Box>
    </React.Fragment>
  );
}
Screenshot 2022-02-17 at 23 00 45

https://codesandbox.io/s/fixedcontainer-material-demo-forked-9u3fl8?file=/demo.js

I was almost going to propose to add documentation about it in https://mui.com/components/container/ but if we start to document this, where do we start? So I'm not sure, closing for now.

aress31 commented 2 years ago

Simple @oliviertassinari add a switch to replace the Container margin by a padding for these use cases and problem solved and more use case coverage without hacking parent boxes or faffing around with the CSS andf selectors...