Aligning logo to center with Material-UI - css

Trying to center a logo in my log in form with Material-UI, everything else appears to be centered exception of the logo which is hugging the left side of the card.
I've tried adding align="center" and justify="center" under the img tag but it still is not moving the image in the center of the card. I've also tried adding a "gridItem" alignItems:'center' under my const styles
const styles = theme => ({
logo: {
padding: "1rem",
width: 300,
[theme.breakpoints.down("sm")]: {
width: 200,
}
},
appName: {
color: '#2979ff',
[theme.breakpoints.down("sm")]: {
fontSize: theme.typography.h5.fontSize
}
},
});
<Grid container justify="center" alignItems="center">
<Grid item>
<Card>
<Grid item>
<img className={classes.logo} alt="Portal Logo" src={Logo} align="center" />
</Grid>
I am expecting the logo to be centered in my my "login" form that I've created.

You are using flexbox so better to use justifyContent: center; on parent element like .
<Grid container justify="center" alignItems="center">
<Grid item>
<Card>
<Grid item justifyContent="center">
<img className={classes.logo} alt="Portal Logo" src={Logo} align="center" />
</Grid>

Try text-align:center for the parent element of logo
HTML
<div class="logo">
<img src="logo.png">
</div>
CSS
.logo{
text-align:center;
}

Related

Material UI Grid Items are overlapping

I am using Material UI for styling my react components but if I put some other elements on grid columns then they start overlapped with each other.
import { Grid } from "#material-ui/core";
import ReactPlayer from "react-player/file";
const MyReactlayer = () => {
return (
<div>
<h2>"test"</h2>
<Grid container wrap={"nowrap"}>
<Grid item md={9}>
<Grid container wrap={"nowrap"} direction={"column"}>
<Grid item md={12}>
<div className="VPlayer">
<ReactPlayer
height={"100%"}
width={"100%"}
url={"../../video/sample.mp4"}
muted={true}
playing={true}
/>
</div>
</Grid>
<Grid item md={12}>
<div className="BControls">
</div>
</Grid>
</Grid>
</Grid>
<Grid item md={3} className="RControls">
</Grid>
</Grid>
</div>
);
};
export default MyReactlayer;
My css file contain style only for two elements:
.VPlayer{
height: 100%;
width: 100%;
}
.BControls{
height: 50px;
background-color: #3fb8f7;
width: 100%;
}
I attached the output screenshot also

Make Material UI Grid container grow with flexGrow

I am creating a chat window where I have my users on the left and my messages on the right.
The thing is I want both columns to grow to the end of the viewport or till the footer but there is no way to make it works. Here is my component.
import Grid from "#material-ui/core/Grid";
const Prueba = () => {
return (
<div style={{ display: "flex" }}>
<Grid container spacing={1} style={{ flexGrow: 2 }}>
<Grid
item
xs={12}
sm={12}
md={4}
lg={3}
style={{ background: "black" }}
></Grid>
<Grid
item
xs={12}
sm={12}
md={8}
lg={9}
style={{ background: "blue" }}
></Grid>
</Grid>
<div
style={{
position: "fixed",
bottom: 0,
height: 100,
width: "100%",
backgroundColor: "red",
}}
></div>
</div>
);
};
export default Prueba;
The container is inside a flex element and the Grid Container has flexGrow property 1. What is not working here?
Here is how it renders now. It's like my Grid container has no height and actually I want it to grow all down to the footer.
You can do this in material-ui with css grid
https://codesandbox.io/s/naughty-yonath-wqr1p?file=/src/App.js
import { styled } from "#material-ui/core";
const Grid = styled("div")({
display: "grid",
gridTemplateColumns: "1fr 3fr",
height: "100vh"
});
const Footer = styled("div")({
position: "fixed",
bottom: 0,
height: 100,
width: "100%",
backgroundColor: "tomato"
});
export default function App() {
return (
<div className="App">
<Grid>
<div style={{ background: "khaki" }}>Left</div>
<div style={{ background: "lightsalmon" }}>Right</div>
</Grid>
<Footer />
</div>
);
}

Material-UI Grid: Can I apply the background color to only cells, and not the empty spaces outside them?

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>
);
}

Purpose of flexGrow in the parent div of a Material UI grid?

I'm trying to understand this code example, https://codesandbox.io/s/9rvlm, from the examples in the Material UI docs (https://material-ui.com/components/grid/):
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Grid from '#material-ui/core/Grid';
const styles = theme => ({
root: {
flexGrow: 1,
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
});
function CenteredGrid(props) {
const { classes } = props;
return (
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=12</Paper>
</Grid>
<Grid item xs={6}>
<Paper className={classes.paper}>xs=6</Paper>
</Grid>
<Grid item xs={6}>
<Paper className={classes.paper}>xs=6</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>xs=3</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>xs=3</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>xs=3</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>xs=3</Paper>
</Grid>
</Grid>
</div>
);
}
CenteredGrid.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(CenteredGrid);
My question is: what is the purpose of assigning flexGrow: 1 to the parent div element?
As I understand from https://material-ui.com/system/flexbox/#flex-grow and https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow, flex-grow is a CSS property of items of flex containers. In this example though, I don't see there being a flex container element containing this component; the CenteredGrid is displayed (as <Demo/>) directly in the root div.
Are the styles.root applied to the parent div 'just in case' the component is rendered in a flex container? I'd appreciate some clarification.
The comment by Anthony mentioned above seems the right answer to me. If the parent is set to display:flex and child component being loaded does not have flex:1 or flex-grow:1 then it will not take up 100% width of the parent.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div style="border:1px solid black; padding:2px; ">
<div style="border:1px solid red; ">parent is not flex container - child div takes 100% width</div>
</div>
<br/>
<div style="border:1px solid black; padding:2px; ">
<div style="border:1px solid red; flex-grow:1; ">parent is not flex container - child div takes 100% width</div>
</div>
<br/>
<div style="border:1px solid black; padding:2px; display:flex; ">
<div style="border:1px solid red; ">parent is flex container - sorry</div>
</div>
<br/>
<div style="border:1px solid black; padding:2px; display:flex; ">
<div style="border:1px solid red; display:flex; flex-grow:1;">parent is flex container - child div takes 100%</div>
</div>
</body>
</html>
The comment of AnthonyZ said:
The only time it would make a difference is when there is a flex
parent.
But in a React App the outer Div in the Body is not the outer-most parent.
In HTML/CSS that is the HTML and the BODY.
In a create-react-app they get the default "display:block" in either index.css or base stylesheet (of the browser).
I solved it by doing the following:
Move index.css to public
Seriously, why is index.css in /src and index.html in /public ??
Modify index.css
Specify "display:flex" for both HTML and BODY in index.css
html {
display: flex;
min-height: 100%;
}
body {
margin: 0;
min-height: 100%;
display:flex;
flex-grow: 1;
}
Modify App.js
In App.js create an outer div
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
}));
// ....
function App() {
const classes = useStyles();
return (
<div className={classes.root}>
<Provider store={store}>
<BrowserRouter>
<TopMenu/>
<AllRoutes/>
</BrowserRouter>
</Provider>
</div>
);
}
TopMenu.js
const useStyles = makeStyles((theme) => ({
offset: theme.mixins.toolbar,
title: {
flexGrow: 1,
},
}));
export default function TopMenu() {
const classes = useStyles();
return (
<React.Fragment>
<AppBar position="fixed">
<Toolbar variant='dense'>
<Typography variant="h6" className={classes.title}>
Application Title
</Typography>
<MainMenu/>
</Toolbar>
</AppBar>
<div className={classes.offset}/>
</React.Fragment>
);
}
If you inspect the elements, you'll see that the whole height is taken started from the HTML-tag.
Problem with this solution: That annoying scrollbar which takes lets you scroll the height of the AppBar.
If somebody has a solution for that, I'll edit my answer (or delete the answer when there's a far better solution :-) )

Make Item go the bottom using Flexbox and Material UI

I am trying to add Unassigned Text to the bottom of my Container, as shown in this mockup:
Below is the code, that I have so far. I am struggling to get the border between the play button working too. I have tried the usual css: bottom:0 and position:relevant Along with Flexbox but it doesn't seem to want to go to the very bottom of the container.
const styles = theme => ({
root: {
flexGrow: 1,
overflow: 'hidden',
padding: theme.spacing(0, 3),
},
paper: {
maxWidth: 800,
margin: `${theme.spacing(2)}px auto`,
padding: theme.spacing(2),
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 200,
},
playButton: {
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
position: "relative",
"& .playButton": {
position: "absolute",
top: "60%",
left: "-55px",
transform: "translateY(-50%)",
},
"& .star-rating": {
"& .fa-star": {
"&:hover": {
"&::before": {
content: "\f005",
color: "yellow"
}
}
}
},
},
});
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>
{props.name}
</Typography>
<div className="form-divider"></div>
<Typography variant="body2" color="textSecondary">
{props.description}
</Typography>
</Grid>
</Grid>
<Grid item classes={{ root: props.classes.playButton}}>
<Grid item xs={3} className="playButton">
<i class="far fa-play-circle fa-2x"></i>
</Grid>
<div className="workers-assigned-label">
Workers Assigned
</div>
<Typography variant="h6" gutterBottom>
0/25
</Typography>
<div class="star-rating">
<label class="far fa-star fa-2x"></label>
<label class="far fa-star fa-2x"></label>
<label class="far fa-star fa-2x"></label>
</div>
<div className="dropdown-menu">
<h5>Unnassigned</h5>
</div>
</Grid>
</Grid>
</Grid>
</Paper>
</div>
);
}
export default withStyles(styles)(Tasks);
Any input would be great.
I would recommend starting with a Grid 'skeleton' that looks something like:
<Grid container>
<Grid item container xs={8} direction="column" justify="flex-start">
// Left column contents, with each row as a <Grid item>
</Grid>
<Fab className={classes.fab}><PlayIcon /><Fab>
<Grid item container xs={4} direction="column" justify="space-between" className={classes.right}>
// Right column contents, with each row as a <Grid item>
</Grid>
</Grid>
The direction=column will help you position items vertically within each container. The justify=space-between will ensure that your first item is at the top of the container and your last item (the unassigned text) is at the bottom.
The "right" css class looks like:
right: {
borderLeft: `1px solid ${theme.palette.grey[500]}`,
position: "relative"
}
You can give it a position of "relative" to make it easier to position the fab relative to the column. The "fab" class looks like:
fab: {
position: "absolute",
margin: "auto",
top: 0,
bottom: 0,
left: -28
}
The margin, top, and bottom properties help center the fab vertically, and the left is a bit of a hack based on the dimensions of the fab to center it over the border.
Here's a working draft that brings everything together: https://codesandbox.io/s/tender-torvalds-dlbke?fontsize=14
You can try something like this, or give flex: 1 to anything in the column to make it stretch.
const styles = theme => ({
playButton: {
'& .dropdown-menu': {
marginTop: "auto"
}
}
})

Resources