I make a react material ui AppBar.
There is a logo and tabs.
The tabs should be in the center of the AppBar and the logo on the left.
But I can't make the logo go to the left.
How can I make it to go the left?
I am using mui's Grid system but if there is better solution doesn't matter.
Here is a live example https://codesandbox.io/embed/delicate-feather-mmf3k
const Header = () => {
const classes = useStyles();
const [value, setValue] = React.useState(0);
return (
<nav className={classes.root}>
<AppBar position="static" color="default">
<Toolbar style={{ alignItems: "center", justifyContent: "center" }}>
<Grid justify={"center"} alignItems={"center"} container>
<Grid style={{ justifySelf: "flex-start" }} item>
<img
className={classes.logo}
src={
"https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg"
}
alt="Logo"
/>
</Grid>
<Grid item>
<Grid container justify={"center"}>
<Tabs
onChange={(e, v) => setValue(v)}
value={value}
aria-label="Navigation Tabs"
>
<Tab label={"page 1"} />
<Tab label={"page 2"} />
</Tabs>
</Grid>
</Grid>
</Grid>
</Toolbar>
</AppBar>
</nav>
);
};
In this case both the Logo and Tabs are in the center.
I tired to style justifySelf, alignSelf to flex-start on the logo to no avail.
Adding xs to the second Grid item, makes the logo to go to left but the Tabs are not exactly in the center in this case.
The solution I came up with is to add empty 3rd Grid item.
Justify 'space-between' on the Grid container.
Give xs={1} to the first Grid item, in which is the logo.
Give xs={4} to the tabs Grid item.
Give xs={1} to the third Grid item.
const Header = () => {
const classes = useStyles();
const [value, setValue] = React.useState(0);
return (
<nav className={classes.root}>
<AppBar position="static" color="default">
<Toolbar>
<Grid justify={"space-between"} container>
<Grid xs={1} item>
<img
className={classes.logo}
src={
"https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg"
}
alt="Logo"
/>
</Grid>
<Grid xs={4} item>
<Grid container justify={"center"}>
<Tabs
onChange={(e, v) => setValue(v)}
value={value}
aria-label="Navigation Tabs"
>
<Tab label={"page 1"} />
<Tab label={"page 2"} />
</Tabs>
</Grid>
</Grid>
<Grid item xs={1} />
</Grid>
</Toolbar>
</AppBar>
</nav>
);
};
Working demo: https://codesandbox.io/s/great-cloud-zwghk
Related
I have a Grid container containing four Grid items. The first Grid item is full width and contains a title. The other three Grid items contain avatars. I want to align the avatars to the right of the page and I would like the title to align with the left-most avatar. However, it is currently further to the left than the avatars. The other issue is that the number of avatars can vary (likely between 1 and 3 but possibly more). How can I ensure the left-most avatar and title align?
Here is the result I am getting:
And here is what I would like to achieve:
Here is my code:
import React from "react";
import { Grid, makeStyles, Typography, Divider, Avatar } from "#material-ui/core";
const useStyles = makeStyles((theme) => ({
header: {
paddingTop: theme.spacing(3),
paddingBottom: theme.spacing(3),
flexGrow: 1,
},
}));
const Header = ({ padding }) => {
const classes = useStyles();
return (
<>
<Grid
container
item
direction="row"
justify="space-between"
align-items="center"
xs={12}
className={`${padding} ${classes.header}`}
>
{/*Page title and description*/}
<Grid item xs>
<Typography variant="h1" component="h1">
Page Title
</Typography>
<Typography variant="body1">
This is a description of what the page is about
</Typography>
</Grid>
{/*People container*/}
<Grid item xs className={classes.smeSection} alignItems="bottom">
{/*People profiles*/}
<Grid container item justify="flex-end" alignItems="bottom">
<Grid item xs={12}>
<Typography variant="h5">People</Typography>
</Grid>
<Grid item>
<Avatar/>
</Grid>
<Grid item>
<Avatar/>
</Grid>
<Grid item>
<Avatar />
</Grid>
</Grid>
</Grid>
</Grid>
<Divider />
</>
);
};
export default Header;
Many thanks!
Katie
By continuously nesting flexbox components it is very easy to make mistakes and get lost in the code.
If it was that I understood your requirement well, here is the code with which I managed to get that layout:
import React from "react";
import { Grid, Typography, Divider, Avatar } from "#material-ui/core";
const Header = () => {
return (
<>
<Grid container direction="row" align-items="center">
{/*Page title and description*/}
<Grid item xs={9}>
<Typography variant="h1" component="h1">
Page Title
</Typography>
<Typography variant="body1">
This is a description of what the page is about
</Typography>
</Grid>
{/*People container*/}
<Grid container item xs={3}>
{/*People profiles*/}
<Grid container item>
<Grid item>
<Typography variant="h5">People</Typography>
</Grid>
<Grid container>
<Grid item>
<Avatar />
</Grid>
<Grid item>
<Avatar />
</Grid>
<Grid item>
<Avatar />
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Divider />
</>
);
};
export default Header;
A grid can be "container", "item" or both. The most important changes I made to your code was to make all grid parents "containers" and add a width size to the first two grid items (xs={9} and xs={3}).
Here's a CodeSandbox with a working example: https://codesandbox.io/s/upbeat-banzai-0gp10?file=/src/Header.js:0-1119
In my opinion, I think a better alternative is to use a combination of Grid (for general layout) and Flexbox to align the nested elements.
UPDATE:
With the new data you added as a reference I made the layout again using flexbox.
import React from "react";
import {
Typography,
makeStyles,
Avatar,
Card,
CardHeader,
Divider
} from "#material-ui/core";
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
justifyContent: "space-between"
},
usersHeader: {
marginLeft: theme.spacing(2)
},
personCards: {
display: "flex"
}
}));
const Header = () => {
const classes = useStyles();
return (
<>
<div className={classes.root}>
<div>
<Typography variant="h3" component="h1">
Page Title
</Typography>
<Typography variant="body1">
This is a description of what the page is about
</Typography>
</div>
<div>
<Typography className={classes.usersHeader} variant="subtitle">
Users
</Typography>
<div className={classes.personCards}>
<Card elevation={0}>
<CardHeader
avatar={<Avatar />}
title="Person name"
subheader="Person role"
/>
</Card>
<Card elevation={0}>
<CardHeader
avatar={<Avatar />}
title="Person name"
subheader="Person role"
/>
</Card>
<Card elevation={0}>
<CardHeader
avatar={<Avatar />}
title="Person name"
subheader="Person role"
/>
</Card>
</div>
</div>
</div>
<Divider />
</>
);
};
export default Header;
CodeSandbox reproduction: https://codesandbox.io/s/condescending-cartwright-grxhj?file=/src/Header.js
On a particular offset value or section entry, I need to make the card a sticky card (which is having an id "sticky Card") that exist in a particular grid column of the grid container. I am using offset y value to add condition when the card needs to be sticky. Let me know of any possibilities. As of now, sticky is not working inside container&grid
if (window.pageYOffset > 1500 && window.pageYOffset < 2000) {
document.getElementById("stickyCard").style.position = "sticky";
document.getElementById("stickyCard").style.top = "100px";
document.getElementById("stickyCard").style.zIndex = "1";
} else{
document.getElementById("stickyCard").style.position = "relative";
document.getElementById("stickyCard").style.top = "0px";
document.getElementById("stickyCard").style.right = "0px";
document.getElementById("stickyCard").style.zIndex = 0;
}
<div name="key-features">
<Box
component="section"
className={classes.root}
paddingY={8}
mx="auto"
>
<Container maxWidth="lg">
<Grid container spacing={2} direction="row">
<Grid item xs={9}>
<Typography
variant="h2"
className={classes.heading}
gutterBottom
component="h2"
align="left"
>
{data.heading}
</Typography>
<div className={classes.grideRoot}>
<Grid container spacing={4}>
{data.trainingList.map((item, index) => (
<Grid
key={index}
item
item
xs={12}
sm={6}
md={4}
lg={4}
>
<TrainingOverViewCard data={item} />
</Grid>
))}
</Grid>
</div>
</Grid>
<Grid
item
xs={3}
>
<Grid
container
direction="column"
justify="center"
alignItems="center"
>
<div id="stickyCard">
<SelectedScheduleBanner />
{/* <RequestCallBackCard/> */}
</div>
</Grid>
</Grid>
</Grid>
</Container>
</Box>
</div>
I'm trying to create a grid system with a gradient background color. However, the background color also applies to the empty spaces not taken up by grid cells. I want just the grid cells to share this gradient. Is there any way to do this?
Image: https://imgur.com/a/WHVhFg1
You should set a linear background color for your container and set background: 'inherit' for your grid item. Inside your grid item, you should use an image with a no background color.
Try this:
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";
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
background:
"linear-gradient(90deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%)"
},
paper: {
padding: theme.spacing(2),
textAlign: "center",
color: theme.palette.text.secondary,
background: "inherit"
}
}));
export default function AutoGrid() {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={3}>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item xs>
<Paper className={classes.paper}>
<img
height="100px"
alt="cat"
src="http://assets.stickpng.com/thumbs/584c3c8a1fc21103bb375ba7.png"
/>
</Paper>
</Grid>
</Grid>
</div>
);
}
I need some help with positioning my Grid Items while using Material UI.
Codesandbox is where I am so far (roughly).
And my question is quite simple - how do I get 2 & 3 to go to the right of 1? I kinda do it but there are all those weird spaces to the left and down that, I cannot figure out how to deal with.
That's the end result I'm after:
Thank you.
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Typography from "#material-ui/core/Typography";
import Paper from "#material-ui/core/Paper";
import Divider from "#material-ui/core/Divider";
import Grid from "#material-ui/core/Grid";
const useStyles = makeStyles(theme => ({
container: {
// display: "grid",
gridTemplateColumns: "repeat(12, 1fr)",
gridGap: theme.spacing(3)
},
paper: {
padding: theme.spacing(1),
textAlign: "center",
color: theme.palette.text.secondary,
whiteSpace: "nowrap",
marginBottom: theme.spacing(1)
},
w: {
height: "100px"
},
divider: {
margin: theme.spacing(2, 0)
}
}));
export default function CSSGrid() {
const classes = useStyles();
return (
<div>
<Grid container spacing={3}>
<Grid container direction="column">
<Grid item xs={8}>
<Paper className={classes.paper + " " + classes.w}>xs=8</Paper>
</Grid>
</Grid>
<Grid
container
style={{ display: "table", height: "100%" }}
direction="row"
>
<Grid item xs={4}>
<Paper className={classes.paper}>xs=4</Paper>
</Grid>
<Grid item xs={4}>
<Paper className={classes.paper}>xs=4</Paper>
</Grid>
</Grid>
</Grid>
<Divider className={classes.divider} />
</div>
);
}
Some notice points from your code
use one container for one grid field structure
remove direction setting direction="column"
xs sum needs to lower or equal to 12 if you want to set them in one row.
Kindly check the material-ui grid document for better understanding
<Grid container spacing={3}>
<Grid item xs={8}>
<Paper className={classes.paper + " " + classes.w}>xs=8</Paper>
</Grid>
<Grid item xs={2}>
<Paper className={classes.paper}>xs=2</Paper>
</Grid>
<Grid item xs={2}>
<Paper className={classes.paper}>xs=2</Paper>
</Grid>
</Grid>
<Divider className={classes.divider} />
Update:
<Grid container spacing={3}>
<Grid item xs={8}>
<Paper className={classes.paper + " " + classes.w}>xs=8</Paper>
</Grid>
<Grid item xs={4}>
<Grid container>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=4</Paper>
</Grid>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=4</Paper>
</Grid>
</Grid>
</Grid>
</Grid>
<Divider className={classes.divider} />
Try it online:
I am looking for some advice regarding this layout. I am struggling to get the play button in the middle with the borders. I have the following code so far, I am just struggling with getting flexbox to position the play button.
function Tasks(props) {
const { classes } = props;
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<Grid container spacing={2}>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<div className="name-label">
Name
</div>
<Typography variant="h6" gutterBottom>
Order cofee beans
</Typography>
<div className="form-divider"></div>
<Typography variant="body2" color="textSecondary">
Process of Description
</Typography>
</Grid>
</Grid>
<Grid item>
<Typography variant="subtitle">Workers Assigned</Typography>
<Grid item xs={3}>
<i class="far fa-play-circle"></i>
</Grid>
<Typography variant="h6" gutterBottom>
0/25</Typography>
</Grid>
</Grid>
</Grid>
</Paper>
</div>
);
}
Currently, I am unsure if the Grid is the issue or if I need to better structure what I have, any feedback would be much appreciated. I have an image of what it should look like:
Image
I wouldn't use flex to position the button like that. It looks like you'd want something like:
const styles = theme => ({
box1: {
display: "flex",
position: "relative",
"& .playButton": {
position: "absolute",
top: "50%",
transform: "translateY(-50%)"
}
}
});
const YourComponent = props => (
<div>
{...}
<Grid item classes={{ root: props.classes.box1}}>
<Typography variant="subtitle">Workers Assigned</Typography>
<Grid item xs={3} className="playButton">
<i class="far fa-play-circle"></i>
</Grid>
<Typography variant="h6" gutterBottom>0/25</Typography>
</Grid>
{...}
</div>
);
YourComponent = withStyles(styles)(YourComponent);