What is the purpose of sx prop in Material UI? - css

<Box style={{ padding: "20px" }}>
<Post post={post} setCurrentId={setCurrentId} />
</Box>
<Box sx={{ padding: "20px" }}>
<Post post={post} setCurrentId={setCurrentId} />
</Box>
React.js + Material UI
The above two examples do the same thing, one uses sx prop in material UI, the other is regular inline styling using css, so what is the point of "sx"? and should it always be used over style={{}} when using Material UI?

The sx prop is a shortcut for defining custom style that has access
to the theme
It can accept any CSS properties plus a few extra from MUI.
There are differences like :
shortHand: padding-top can be written as pt.
access to theme: If you define your theme in material UI, sx prop can directly access its properties like color.
Example from the doc :
import * as React from 'react';
import { Box, ThemeProvider, createTheme } from '#mui/system';
const theme = createTheme({
palette: {
background: {
paper: '#fff',
},
text: {
primary: '#173A5E',
secondary: '#46505A',
},
action: {
active: '#001E3C',
},
success: {
dark: '#009688',
},
},
});
export default function Example() {
return (
<ThemeProvider theme={theme}>
<Box
sx={{
bgcolor: 'background.paper',
boxShadow: 1,
borderRadius: 2,
p: 2,
minWidth: 300,
}}
>
<Box sx={{ color: 'text.secondary' }}>Sessions</Box>
<Box sx={{ color: 'text.primary', fontSize: 34, fontWeight: 'medium' }}>
98.3 K
</Box>
<Box
sx={{
color: 'success.dark',
display: 'inline',
fontWeight: 'bold',
mx: 0.5,
fontSize: 14,
}}
>
+18.77%
</Box>
<Box sx={{ color: 'text.secondary', display: 'inline', fontSize: 14 }}>
vs. last week
</Box>
</Box>
</ThemeProvider>
);
}
Properties in sx object can have functions as valuse. These functions have access to theme too.
<Box sx={{ height: (theme) => theme.spacing(10) }} />
Grid properties: gap, rowGap and columnGap are available in sx.
Responsive styles: You can define properties according to the different MUI device size shorthands:
borderColor : { xs: "red", sm: "green" },
Access to child components: You can change styles of chlid components using nested styles:
<TextField
variant="outlined"
sx={{
'& .MuiInputBase-input': {
color: 'white',
},
}}
/>
Much more than CSS: The sx prop also supports CSS syntax including child and pseudo-selectors, media queries etc.
Eg:
<Box
sx={{
// some styles
":hover": { //psuedo-selectors
boxShadow: 6,
},
'#media print': { //media-queries
width: 300,
},
}}
>
Sources:
1.
2.

The sx props allows you to use all the mui system properties along with CSS properites.
with style={{}} aproch you add the CSS properties directly but you cannot use the mui properties in it. e.g. theme properties.
with SX props: you can set color in theme once. then use same color in all your app. then in future you want to change color you can change it in theme only once and it will apply to all the app automatically.
sx={{ color: 'primary.main' }}
with Style: but then you have to remember exact colorcode while coding your app and then in future if you decided to change you have to change everywhere in app.
style={{ color: '#00ff00' }}
also some CSS properties you can directly add to components.
e.g.
<Box height="100px" >... </Box> is same as
<Box sx={{height: '100px'}}>...</Box>
check below pages for more details.
https://mui.com/system/basics/#all-inclusive
https://mui.com/system/the-sx-prop/

Related

Can I customize my MUI Slider thumb to have bigger text?

I am using the MUI-Slider component in React to display a value. I would like to customize the 'thumb'/valueLabel so the font and thumb are much larger. I read MUI's documentation on updating the CSS to customize the thumb with limited success. My slider looks like this currently. The thumb and dot are blue, but everything else is grey. The font is still very small.
Here is my React component:
Note: the sx usage is copied directly from the MUI documentation.
import { Slider } from '#material-ui/core';
<Slider
disabled
min={0}
max={100}
value={50}
marks={[
{ value: 0, label: '0' },
{ value: 100, label: '100' },
]}
aria-label="Conviction Score"
color="primary"
sx={{
'& .MuiSlider-thumb': {
borderRadius: '1px',
},
}}
valueLabelDisplay="on"
orientation="vertical"
valueLabelFormat={value => `${value.toFixed(1)}`}
></Slider>
I added this to my SCSS. Clearly I can change the thumb color but not any of the font attributes.
color:#0d47a1;
font-size: 20px !important;
font-weight: bold !important;
}
What am I doing wrong? Is there any way I can do this with just CSS?
Use this in your sx in the Slider component to replace the one you have now.
sx={{
"& .MuiSlider-thumb": {
borderRadius: "1px"
},
"& .MuiSlider-valueLabelLabel": {
fontSize: "20px",
fontWeight: "bold",
color: "#0d47a1"
}
}}

Remove border around material-ui v4 textbox

I am using Material-UI version 4 and not the latest mui v5.
I have tried the following to no avail. I just want to remove/hide the border around the textfield component.
<TextField
disabled={true}
variant="standard"
InputProps={{
style: { backgroundColor: '#d6eaf8', fontSize: '18px', color: 'black' },
underline: {
"&&&:before": {
borderBottom: "none"
},
"&&:after": {
borderBottom: "none"
}
}
}}
/>
If you only want to remove the material ui underline border you simply use the "disableUnderline: 'true'" property like this:
<TextField
disabled={true}
variant="standard"
InputProps={{
disableUnderline: 'true',
style: {
backgroundColor: "#d6eaf8",
fontSize: "18px",
color: "black"
}
}}
/>
If you want to have all the TextInputs look the same I would recommend setting up a custom Theme, though.
updated:
Another way of removing the border is to fiddle around with the CSS Global classes such as:
const StyledTextField = withStyles({
root: {
"& .MuiOutlinedInput-root": {
backgroundColor: "lightblue",
"& fieldset": {
border: "none"
}
}
}
})(TextField);
return <StyledTextField variant="outlined" />;
updated 2:
or if you rather use a custom theme:
const theme = createTheme({});
theme.overrides = {
MuiOutlinedInput: {
root: {
backgroundColor: 'lightblue',
},
notchedOutline: {
border: "none"
}
}
};
...
<ThemeProvider theme={theme}>
<TextField variant="outlined" />
</ThemeProvider>

How to change background color of iconbutton when onclick in material ui

When I clicked IconButton the background color changed to an oval shape. I need to change the background color after onclick
CSS
CSS for IconButton. Changed the background color when hover. I need the same for onClick
const positionStyle = makeStyles(theme => ({
paper: {
backgroundColor: theme.palette.accent[100],
},
iconButton: {
padding: "10px",
margin: "0 5px 1px 0",
"&:hover, &.Mui-focusVisible, &:active": {
backgroundColor: theme.palette.accent[100],
},
"&$buttonDisabled": {
color: theme.palette.accent[100],
},
},
})
Material UI
<Paper className={classes.paper}>
<Box display={"flex"} height={theme.spacing(2.3)}>
<IconButton
color={"inherit"}
size={"small"}
className={classes.iconButton}
onClick={() => {
history.push("/a")
}}>
<img src={"/static/images//a.svg"} />
<Box pl={1} mt={"-4px"} maxWidth={theme.spacing(10)}>
<Typography variant={"subtitle1"} component="p">
{" Hello"}
</Typography>
</Box>
</IconButton>
</Box>
</Paper>
as i read here
Can I have an onclick effect in CSS?
the best way to do this is a checkbox trick,
other solutions are also on the page i linked
either if you have more liberty you can use JS
Have a good day

Small circle appears as ellipse in react

I want to create a button in the shape of a circle in react. It works for big sizes (px > 100) but looks like an ellipse for smaller pixels.
return (
<React.Fragment>
<ThemeProvider theme={theme}>
<Button style= {{
width:'10px',
height:'10px',
borderRadius:'50%',
fontSize:'10px',
color:'#fff',
lineHeight:'50px',
textAlign:'center',
background:'#000'
}}
variant="contained" color="secondary">
{"Theme nesting"}
</Button>
</ThemeProvider>
</React.Fragment>
);
This is what is looks like:
I know the CSS is correct, so what causes this behavior?
There are other CSS styles being applied to the Button from Material-UI (mainly padding: 6px 16px; and min-width: 64px).
This will display a black circle:
<ThemeProvider theme={theme}>
<Button
style={{
width: "10px",
height: "10px",
borderRadius: "50%",
fontSize: "10px",
color: "#fff",
lineHeight: "50px",
textAlign: "center",
background: "#000",
minWidth: "unset",
padding: "0"
}}
variant="contained"
color="secondary"
>
Theme nesting
</Button>
</ThemeProvider>
That said, a better alternative to using the style property would be to use their styling API for CSS overrides (like makeStyles with theming).

Overriding existing Mui classes using makeStyles

So, this can be a very minute implementation issue on my end I think. I used to keep stylesheets completely separate from my component.js file but lately, I started to see some benefits of writing styles inside the component with styled components, emotions, make styles, etc. I tried it on a dummy project and started to implement it out on some components on an app I am working on right now. The reasons were primarily more manageable, dev-experience, and it worked for me.
But then I found myself in this issue of overriding existing mui styles.
For example, I am using material-ui to make this accordion component. And there is a nested property
.MuiAccordionSummary-root.Mui-expanded {
min-height: 64px;
}
To edit this is my sass file would be very easy but how do I make it work with make styles?
My current styles look like this
const useStyles = makeStyles((theme) => ({
root: {
borderBottom: '0.5px solid',
borderBottomColor: theme.palette.primary.main,
marginBottom: '16px',
maxHeight: '35px',
},
summary: {
backgroundColor: theme.palette.complimentory.main,
borderBottom: '0.5px solid',
borderBottomColor: theme.palette.primary.main,
maxHeight: '35px',
height: '35px',
},
title: {
fontFamily: 'Helvetica',
fontStyle: 'normal',
fontWeight: 'normal',
fontSize: '14px',
lineHeight: '14px',
letterSpacing: '0.266667px',
textTransform: 'uppercase',
},
content: {
marginTop: '15px',
fontSize: '14px',
fontStyle: 'normal',
lineHeight: '16.8px',
letterSpacing: '0.375px',
fontWeight: '400',
fontFamily: 'Helvetica',
textAlign: 'left',
},
}))
I am struggling to target it inside makestyles, I think it must be possible, I just am having a hard time as I am not used to it.
You should use <StyledEngineProvider injectFirst> at the root of you project
import { render } from "react-dom";
import { StyledEngineProvider } from "#mui/material";
import App from "./App";
const rootElement = document.getElementById("root");
render(
<StyledEngineProvider injectFirst>
<App />{" "}
</StyledEngineProvider>,
rootElement
);
import * as React from "react";
import AppBar from "#mui/material/AppBar";
import Box from "#mui/material/Box";
import Toolbar from "#mui/material/Toolbar";
import Typography from "#mui/material/Typography";
import Button from "#mui/material/Button";
import IconButton from "#mui/material/IconButton";
import MenuIcon from "#mui/icons-material/Menu";
import makeStyles from "#mui/styles/makeStyles";
const useStyles = makeStyles((theme) => {
return {
root: {
backgroundColor: "red",
color: "pink"
}
};
});
export default function App() {
const classes = useStyles();
return (
<Box sx={{ flexGrow: 1 }}>
<AppBar position="static" className={classes.root}>
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
News
</Typography>
<Button color="inherit">Login</Button>
</Toolbar>
</AppBar>
</Box>
);
}
Working demo here https://codesandbox.io/s/wizardly-stonebraker-qnh3t
I'll use the AccordionSummary as an example on how to override existing styles. The Accordion Summary has 6 CSS rules that can be overridden: root, expanded, focused, disabled, content and expandIcon. You can see this at the CSS section of the AccordionSummary API page in Material UI's official documents. Each of these correspond to a Material UI class for the respective component e.g. root for the AccordionSummary corresponds to the class .MuiAccordionSummary-root. To override these styles, you do it via overriding styles with classes.
Using your example:
Create the class name and add the styling in makeStyles. I'll create one called summaryExpanded and will include the styling minHeight: '64px'.
const useStyles = makeStyles((theme) => ({
root: {
borderBottom: '0.5px solid',
borderBottomColor: theme.palette.primary.main,
marginBottom: '16px',
maxHeight: '35px',
},
summary: {
backgroundColor: theme.palette.complimentory.main,
borderBottom: '0.5px solid',
borderBottomColor: theme.palette.primary.main,
maxHeight: '35px',
height: '35px',
},
summaryExpanded: {
minHeight: '64px',
},
title: {
fontFamily: 'Helvetica',
fontStyle: 'normal',
fontWeight: 'normal',
fontSize: '14px',
lineHeight: '14px',
letterSpacing: '0.266667px',
textTransform: 'uppercase',
},
content: {
marginTop: '15px',
fontSize: '14px',
fontStyle: 'normal',
lineHeight: '16.8px',
letterSpacing: '0.375px',
fontWeight: '400',
fontFamily: 'Helvetica',
textAlign: 'left',
},
}))
Override the style in the AccordionSummary component by accessing the relevant rule name and assigning your custom class. In this case, it is expanded, as we are looking to override .Mui-expanded in the AccordionSummary component.
const classes = useStyles();
<Accordion>
<AccordionSummary
classes: {{
expanded: classes.summaryExpanded,
}}
>
</AccordionSummary>
<AccordionDetail>
</AccordionDetail>
</Accordion>
You can do something like this - play around override properties.
import { Overrides } from "#material-ui/core/styles/overrides";
const overrides: Overrides = {
MuiExpansionPanelSummary: {
root: {
minHeight: "3.25rem",
"&$expanded": {
minHeight: "3.25rem",
},
},
content: {
margin: "0.25rem",
"&$expanded": {
margin: "0.25rem",
},
},
expandIcon: {
padding: "0.5rem",
},
expanded: {},
},
};

Resources