How do align content to the center in flexbox - css

I have a item that i want to be align to the middle and one to the bottom.
I want the logo image in the center, but I can't figure out how to do it.
import React, { Component } from 'react';
import { Container, Content, Text, Button, View } from 'native-base';
import { StyleSheet, Image } from 'react-native'
export default class WelcomeScreen extends Component {
render() {
return (
<Container>
<Content contentContainerStyle={styles.container}>
<View style={styles.imgContainer}>
<Image
source={require('../../assets/images/logos/logo.png')}
/>
</View>
<View style={styles.btnContainer}>
<Button block primary onPress={() => this.props.navigation.navigate('Signin')} rounded>
<Text>Sign in</Text>
</Button>
<Button block light style={{ marginTop: 15 }} onPress={() => this.props.navigation.navigate('Signup')} rounded>
<Text>Sign up</Text>
</Button>
</View>
</Content>
</Container>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
imgContainer: {
flex: 1,
},
btnContainer: {
width: 300,
}
})

Try this
imgContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}

Here's an HTML CSS only example for you that you can easily tweak to solve your problem.
body {
margin: 0;
}
#main {
display: flex;
flex-direction: column;
height: 100vh;
justify-content: space-between;
}
.container {
align-items: middle;
margin: 0 auto;
align-self: middle;
width: 300px;
height: 80px;
background-color: steelblue;
vertical-align: afar;
}
<div id="main">
<div class="container">
abc
</div>
<div class="container">
xyz
</div>
</div>
The trick lies in the following CSS properties:
flex-direction: column
justify-content: space-between

if you want the image to align center in the screen except for the button height, you can use the following code, and replace the view in ImageContainer to Image
render() {
return (
<Container>
<View
style={styles.imgContainer}>
<View style={{backgroundColor:'red',height:50,width:50}} />
</View>
<Content contentContainerStyle={styles.container}>
<View style={styles.btnContainer}>
<Button block primary onPress={() => this.props.navigation.navigate('Signin')} rounded>
<Text>Sign in</Text>
</Button>
<Button block light style={{ marginTop: 15 }} onPress={() => this.props.navigation.navigate('Signup')} rounded>
<Text>Sign up</Text>
</Button>
</View>
</Content>
</Container>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'flex-end'
},
imgContainer: {
position:'absolute',
justifyContent:'center',
alignItems:'center',
height:Dimensions.get('window').height-40,
width:Dimensions.get('window').width,
flex: 1,
},
btnContainer: {
height:200,
width: 300,
alignItems:'center',
justifyContent: 'flex-end',
marginBottom:20
}
})

Related

Why is flex container wrapper the flex items despite exceeding 100%?

I want to make a 3 x 6 matrix. I used flexbox and all the flexItems have a flex-basis of 1/6.
At full screen, its how I want it. However, if you make it a smaller screen it starts to wrap. I don't want to break the 3 x 6
https://codesandbox.io/s/vibrant-spence-gski65
import "./styles.css";
import React, { useState } from "react";
const gridValues = new Array(18).fill(0);
export default function App() {
const [grid, setGrid] = useState<number[]>(gridValues);
return (
<div
style={{
width: "90%",
height: "100%"
}}
>
<div
style={{
display: "flex",
flexWrap: "wrap",
padding: "16px"
}}
>
{grid.map((num, i) => {
return (
<span
key={i}
style={{
display: "flex",
flexBasis: "16.666%",
cursor: "pointer",
justifyContent: "center",
padding: "16px",
border: "1px solid black",
flexShrink: 0
}}
>
<span style={{ opacity: 0 }}>{num}</span>
</span>
);
})}
</div>
</div>
);
}
https://codesandbox.io/s/vibrant-spence-gski65?file=/src/App.tsx
Ended up using CSS grid instead after listening to comment. Definitely much easier
import "./styles.css";
import React, { useState } from "react";
const gridValues = new Array(18).fill(0);
export default function App() {
const [grid, setGrid] = useState<number[]>(gridValues);
return (
<div
style={{
width: "90%",
height: "100%"
}}
>
<div
style={{
display: "grid",
gridTemplateColumns: "1fr 1fr 1fr 1fr 1fr 1fr",
gridTemplateRows: "1fr 1fr 1fr"
}}
>
{grid.map((num, i) => {
return (
<span
key={i}
style={{
display: "flex",
cursor: "pointer",
justifyContent: "center",
padding: "16px",
border: "1px solid black"
}}
>
<span style={{ opacity: 0 }}>{num}</span>
</span>
);
})}
</div>
</div>
);
}

Fitting layout vertically and horizontally without scrolling/overflow

I'm attempting to create a layout where the app takes up 100% of the vertical and horizontal space without any overflow.
Instead this is what it looks like:
https://stoic-snyder-620f18.netlify.app/
Here's the code. Any idea what could be causing all the divs to be larger than they should be? I've been stuck on this for hours, no idea what to do.
import React, { useState } from "react"
import styled, { createGlobalStyle } from "styled-components"
import { Link } from "gatsby"
import logo_image from "../../static/logo_white_trans.png"
import fb_icon_image from "../../static/fb_icon.png"
import ig_icon_image from "../../static/ig_icon.png"
import yt_icon_image from "../../static/yt_icon.png"
const Global = createGlobalStyle`
* {
margin: 0;
padding: 0;
border: 0;
}
body, html {
height: 100%;
}
`
const Layout = () => {
const [nav, showNav] = useState(false)
return (
<div id='app' style={{ height: '100vh', backgroundColor: 'pink', display: 'grid', gridTemplateRows: '15% 70% 15%' }}>
<Global />
<div id='header' style={{ height: '100%', backgroundColor: 'blue', display: 'grid', gridTemplateColumns: '20% 60% 20%' }}>
<div id='logo' style={{ width: '100%', backgroundColor: 'orange' }} >
<img src={logo_image} />
</div>
<div id='title' style={{ width: '100%', backgroundColor: 'lime' }}>
Title
</div>
<div id='menu' style={{ width: '100%', backgroundColor: 'coral' }}>
</div>
</div>
<div id='content' style={{ height: '100%', backgroundColor: 'teal' }}>
</div>
<div id='footer' style={{ height: '100%', backgroundColor: 'grey', textAlign: 'center', marginTop: '0.25rem', marginBottom: '0.25rem' }}>
<img src={fb_icon_image} style={{ height: '90%', display: 'inline-block' }} />
<img src={ig_icon_image} style={{ height: '90%', display: 'inline-block', marginLeft: '1rem', marginRight: '1rem' }} />
<img src={yt_icon_image} style={{ height: '90%', display: 'inline-block' }} />
</div>
</div>
)
}
export default Layout

Styling Grid to have more elements than text

I have grid from material UI:
Item element
const Item = styled(Paper)(({theme}) => ({
...theme.typography.body2,
padding: theme.spacing(2),
textAlign: 'center',
color: "black",
}));
Structure
<div className="wrapper">
<Typography variant="h3" component="h3">
List of friends
</Typography>
<div className="friends">
<Grid container
direction="row"
rowSpacing={1}
spacing={{xs: 2, md: 3}} columns={{xs: 4, sm: 8, md: 12}}
alignItems="center"
justifyContent="center"
>
{
friends.map((friend, i) => {
return <Grid item xs={4} sm={6} md={6} mt={5}>
<Item className="item"><span>{i}</span>{friend.name}</Item>
</Grid>
})
}
</Grid>
</div>
</div>
With css:
.wrapper{
width: 100%;
position: relative;
align-items: center;
display: flex;
flex-direction: column;
background:#eaeaea
}
.friends{
position: relative;
width: 75%;
}
It looks like this:
However, i would like the number of friend, to be on the left, and highlighted like:
However, how to stile the <span> element to do this? The when i style span to be
span{
position: absolute;
left: 0
width:25%;
height: 100%
}
Then the span is somewhere else, as the material ui uses lot of styling that makes this hell.
when i change it to:
{
countries.map((friend, i) => {
return <Grid item xs={4} sm={6} md={6} mt={5} >
<span> i </span>
<Item className="item">{friend.name}</Item>
</Grid>
})
}
I would need to make adjustments to the Grid elements, adding position relative and such, but im not sure how this would work with responsivity.
Is there simple way to do this?
Or is there any other component i can use instead of Item(Paper) element?
Thanks for help!
You can use display: grid on the Paper element, like so:
<Paper
sx={{
display: 'grid',
grid: 'auto / 25% 75%',
height: 50,
'& > div': {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
},
}}
>
<Box>1</Box>
<Box>Name</Box>
</Paper>
Alternatively, you can do it with flex: 1 and flex: 3, but I think the grid method is easier to set up, since all the logic is in one line.

How to center one item with flexbox in React Native?

I have the following component in React Native:
<View styleName="nav">
<Back />
<Image styleName="logo" style={{ alignItems: "center", alignSelf: "center", justifyContent: "center" }} source={Img} />
</View>
As you can see, I am trying just about everything to center the logo, with no luck. Every example I am seeing for flexbox shows > 2 items.
Nav has the following styles:
.nav {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
height: 70;
padding-top: 20;
}
Logo size is set:
.logo {
width: 100;
height: 40;
}
Right now I am getting something like this:
[<Back Logo]
I want something like this:
[<Back Logo ]
You could set the <Back/> component's flex-basis: 50%;
Maybe silly one, but try to wrap logo into the container and set width of that container and width of <Back /> to 33% like this:
<View styleName="nav">
<Back styleName="back" />
<View styleName="logoContainer">
<Image styleName="logo" style={{ alignItems: "center", alignSelf: "center", justifyContent: "center" }} source={Img} />
</View>
</View>
And in styles:
.logoContainer {
width: 33%;
height: 40;
}
.back {
width: 33%;
}
Try this:-
<View style={{flexDirection: 'row'}}>
<View style={{flex: 2}}> // it may vary according to you want
<Back /> // your Back component
</View>
<View style={{flex: 8, alignItems: 'center'}}> // you can also adjust flex
<Image styleName="logo" source={Img} /> // give height width to image
</view>
</View>
<View style={{flexDirection: 'row', alignItems:'center',justifyContent:'center'}}>
<View style={{position:'absolute',left:10}}> // it may vary according to you want
<Back /> // your Back component
</View>
<View style={{}}>
<Image styleName="logo" source={Img} /> // give height width to image
</view>
</View>

Align Card Buttons on bottom Material UI

I am developing an app in ReactJS and i'm using the following: MaterialUI (for react) and React Flexbox.
The problem i'm having is trying to position the card buttons on bottom (the problem that seems to have spammed the internet in different frameworks).
I am using the card from here -> https://material-ui.com/demos/cards/
I've tried pretty much everything i could think of from align-items to align-self and different display types. I might be missing something here since i usually work with Bootstrap so i hope a CSS Master can help me out. I'll attach the pic below for ref.
Also for ref here's how my code looks in react( ApiPosts is my cards component) ->
<Grid container>
<Grid item xs={12}>
<Paper className={classes.paper}>
<Row className="rowSpacer">
<Col xs>
<Typography variant="title" align="center" color="textPrimary" gutterBottom>
Posts are below
</Typography>
</Col>
</Row>
<Divider />
<ApiPosts />
</Paper>
</Grid>
</Grid>
And finally my cards are wrapped in <Row around="xs"> (4 posts in a row) and each card in a col <Col xs >
Thanks in advance!
Edit: Solved thanks to Ivan's answer.Here's the code in case anyway needs it (working on Material-UI Cards).
.portCardCl {
display: flex;
flex-direction: column;
height:100%;
}
.portBodyCl {
display: flex;
flex: 1 0 auto;
align-items: flex-end;
justify-content: center;
flex-direction: column;
}
.portButCl{
display: flex;
justify-content: flex-start;
}
portCardCl goes on the first <Card>, portBodyCl goes on <CardActionArea> and finally portButCl goes on <CardActions>
Here is example with css-grid.
const {
Button,
createMuiTheme,
CssBaseline,
MuiThemeProvider,
Typography,
Paper,
withStyles,
} = window['material-ui'];
const styles = theme => ({
root: {
display: "grid",
gridTemplateColumns: "repeat(4, 1fr)",
gridGap: "24px",
},
card: {
display: "grid",
gridTemplateRows: "1fr auto",
gridGap: "8px",
minHeight: 280,
backgroundImage: `url(https://via.placeholder.com/100x200)`,
backgroundSize: "cover"
},
body: {
alignSelf: "end",
textAlign: "center"
},
actions: {
display: "flex",
justifyContent: "space-between"
}
});
const Grid = withStyles(styles)(
class Grid extends React.Component {
render () {
const { classes } = this.props;
const cards = [1, 2, 3, 4];
return (
<div className={classes.root}>
{cards.map(c => (
<Paper key={c} className={classes.card}>
<div className={classes.body}>
<Typography variant="subheading">
Test Image
</Typography>
<Typography variant="caption">
Small help text
</Typography>
</div>
<div className={classes.actions}>
<Button>Left</Button>
<Button color="primary">Right</Button>
</div>
</Paper>
))}
</div>
)
}
}
)
const theme = createMuiTheme();
ReactDOM.render((
<MuiThemeProvider theme={theme}>
<Grid />
</MuiThemeProvider>
), document.querySelector("#root"))
<script src="https://unpkg.com/react#latest/umd/react.development.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-dom#latest/umd/react-dom.development.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/#material-ui/core/umd/material-ui.development.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/babel-standalone#latest/babel.min.js" crossorigin="anonymous"></script>
<div id="root"></div>
Here is example of card with flex using only
.card {
padding: 24px;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .13);
background: skyblue;
border-radius: 4px;
font-family: "Helvetica", sans-serif;
display: flex;
flex-direction: column;
height: 280px;
width: 160px;
}
.card__body {
display: flex;
flex: 1 0 auto;
align-items: flex-end;
justify-content: center;
}
.card__actions {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 16px;
}
<div class="card">
<div class="card__body">
Test Text
</div>
<div class="card__actions">
<button>Left</button>
<button>Right</button>
</div>
</div>

Resources