Fitting layout vertically and horizontally without scrolling/overflow - css

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

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

Covering 100% of available vertical space with video?

I'm trying to create a page with a header that takes up the top 15% of the vertical page, a footer that takes up the bottom 10%, and a video in the middle that takes up the rest of the vertical space.
This is the code I'm using, but it looks completely wrong. Any ideas what my mistake is here?
import React, { useState } from "react"
import Header from "./header"
import Footer from "./footer"
import VideoFile from "../../resources/my_video.mp4"
const Index = () => {
const [nav, showNav] = useState(false)
return (
<div>
<Header>
</Header >
<video preload='auto' loop autoPlay muted height="400vh" objectFit="cover" display="block" margin="0 auto">
<source src={VideoFile} type="video/mp4" />
</video>
<Footer>
</Footer>
</div>
)
}
export default Index
Then here's my header.
import React, { useState } from "react"
import styled, { createGlobalStyle } from "styled-components"
import { Link } from "gatsby"
import logo_image from "../../static/logo_white_trans.png"
const Header = () => {
const [nav, showNav] = useState(false)
return (
<div id='header' style={{ height: '100%', backgroundColor: 'blue', display: 'grid', gridTemplateColumns: '20% 60% 20%' }}>
<div id='logo' style={{ width: '100%', backgroundColor: 'orange' }} >
<img alt='logo' src={logo_image} style={{ maxHeight: '15vh', maxWidth: '100%', width: 'auto !important' }} />
</div>
<div id='title' style={{ backgroundColor: 'lime', textAlign: 'center', color: 'white' }}>
Ellephant
</div>
<div id='menu' style={{ width: '100%', backgroundColor: 'coral' }}>
<MenuIcon nav={nav} onClick={() => showNav(!nav)}>
<div />
<div />
<div />
</MenuIcon>
<MenuLinks nav={nav}>
</MenuLinks>
</div>
</div>
)
}
export default Header
And the footer.
import React from "react"
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 Footer = () => {
return (
<div id='footer' style={{ height: '10vh', backgroundColor: 'grey', textAlign: 'center', marginTop: '0.25rem', marginBottom: '0.25rem', position: 'absolute', bottom: 0, left: 50, right: 50 }}>
<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>
)
}
export default Footer

Layout looks correct on my phone (Android) but not friend's (iPhone)

I finished the layout of the website I'm working on, and like how it looks...
But...when my friend opens it on her iPhone, it looks like this.
I can't figure out what's causing this. If I use Chrome Developer Tools and set it to a responsive mobile format, or iPhone X, it resizes properly. Can anyone help me figure out what I'm doing wrong here?
I also had a third person look at it who told me the video isn't playing. So I'm pretty lost, not sure what I'm doing wrong since I can't reproduce the issue myself.
Here is the link if anyone wants to check.
And this is the code for the header.
import React, { useState } from "react"
import styled from "styled-components"
import { Link } from "gatsby"
import logo_image from "../../static/logo_white_trans.png"
import title_image from "../../static/title.png"
const MenuIcon = //Removed
const MenuLinks = //Removed
const Header = () => {
const [nav, showNav] = useState(false)
return (
<div id='header' style={{ height: '100%', backgroundColor: 'black', display: 'grid', gridTemplateColumns: '20% 60% 20%' }}>
<div id='logo' style={{ width: '100%' }} >
<img alt='logo' src={logo_image} style={{ maxHeight: '15vh', maxWidth: '100%', width: 'auto !important' }} />
</div>
<div id='title' style={{ position: 'relative', margin: 'auto', textAlign: 'center' }}>
<img alt='title' src={title_image} style={{ maxHeight: '15vh', maxWidth: '100%', width: 'auto !important' }} />
</div>
<div id='menu' style={{ width: '100%' }}>
<MenuIcon nav={nav} onClick={() => showNav(!nav)}>
<div />
<div />
<div />
</MenuIcon>
<MenuLinks nav={nav}>
<ul>
//Removed
</ul>
</MenuLinks>
</div>
</div >
)
}
export default Header
And here is the index code.
import React, { useState } from "react"
import Header from "./header"
import Footer from "./footer"
import "./style.css"
import VideoFile from "../../resources/vide_file.mp4"
const Index = () => {
const [nav, showNav] = useState(false)
return (
<div style={{ display: "flex", flexDirection: "column" }}>
<Header style={{ alignItems: "flex-start" }}>
</Header >
<video loop autoPlay muted style={{ preload: 'auto', height: "75vh", objectFit: "cover", display: "block", margin: "0 auto", alignItems: "stretch" }}>
<source src={VideoFile} type="video/mp4" />
</video>
<Footer style={{ alignItems: "flex-end" }}>
</Footer>
</div>
)
}
export default Index
A slight tweak to the margin property on your div id='title' element fixes the issue:
margin: '0 auto'
Remember that margin: 'auto' centers elements horizontally and vertically. I believe what's happening is Chromium is properly centering the element within the direct parent container, in this case:
<div id="header" style="height:100%;background-color:black;display:grid;grid-template-columns:20% 60% 20%"></div>
Safari instead is going a level up and centering the element on the grandparent, which is the full viewport height:
<div style="display:flex;flex-direction:column"></div>
Specifying a '0' margin above and below the element forces Safari to move the logo back to the top of the parent element.

Align Title Horizontally Using Material-Ui and CSS

I need to align the title Hello John Joseph Jones horizontally on the top BUT inside the black box.
The problem that it consumes the space vertically.
I don't if my code is good. Feel free to revise if there is a better way to do this.
Codesandbox is here CLICK HERE
<Box m={3}>
<Grid
container
direction="column"
className={classes.container}
spacing={2}
>
{/* <h1>Hello John Joseph Jones</h1> */}
<Grid item xs={6} className={classes.pictureSection}>
<div className={classes.imageSection}>
<img
src="https://picsum.photos/id/237/200/300"
className={classes.img}
alt="no pic"
/>{" "}
<p className={classes.precinctNo}>PR 4838390</p>
<p className={classes.controlNo}>555555</p>
</div>
</Grid>
<Grid item xs={6} className={classes.nameAddressSection}>
<Box className={classes.fontText}>John Joseph Jones</Box>
<Box mt={1} className={classes.fontText}>
26 South Hawthorne Drive Tonawanda, NY 14150
</Box>
<Box mt={1}>
<QRCode size={80} value={"4234432"} />
</Box>
</Grid>
</Grid>
</Box>
I have edited your Code:
Inserted the new h1 tag, styled it, and changed the Grid direction from column to row.
import React from "react";
import { makeStyles } from "#material-ui/styles";
import { Box } from "#material-ui/core";
import Grid from "#material-ui/core/Grid";
import QRCode from "react-qr-code";
import { red } from "#material-ui/core/colors";
const useStyles = makeStyles(() => ({
button: {
color: "white"
},
hideButton: {
visibility: "hidden"
},
imageSection: {
display: "flex",
flexDirection: "column",
justifyContent: "center",
height: "100%"
},
img: {
height: "4cm",
width: "4cm",
},
h1: { // new
fontSize: "0.70rem",
width: "100%",
textAlign: "center",
margin: "0.1rem"
},
precinctNo: {
display: "flex",
justifyContent: "center",
margin: "0",
fontSize: "0.70rem",
fontWeight: "bold",
textTransform: "uppercase",
color: "#000"
},
controlNo: {
display: "flex",
justifyContent: "flex-start",
margin: "0",
fontSize: "0.70rem",
fontWeight: "bold",
textTransform: "uppercase",
color: "#000"
},
boxBorder: {
border: "3px solid black"
},
container: {
width: "8.5cm",
height: "5.5cm",
borderRadius: "3px",
border: "3px solid #000000",
color: "#00000"
},
pictureSection: {
display: "flex",
flexBasis: "100%"
},
nameAddressSection: {
display: "flex",
flexDirection: "column",
textAlign: "center",
flexBasis: "100%",
justifyContent: "space-between"
},
alignItems: {
alignSelf: "center",
textAlign: "center"
},
fontText: {
color: "#000000",
fontSize: "0.70rem",
fontWeight: "bold",
textTransform: "uppercase"
}
}));
const SampleCard = () => {
const classes = useStyles();
return (
<Box m={3}>
<Grid
container
direction="row" // new
className={classes.container}
spacing={2}
>
<h1 className={classes.h1}>Hello John Joseph Jones</h1> // new
<Grid item xs={6} className={classes.pictureSection}>
<div className={classes.imageSection}>
<img
src="https://picsum.photos/id/237/200/300"
className={classes.img}
alt="no pic"
/>{" "}
<p className={classes.precinctNo}>PR 4838390</p>
<p className={classes.controlNo}>555555</p>
</div>
</Grid>
<Grid item xs={6} className={classes.nameAddressSection}>
<Box className={classes.fontText}>John Joseph Jones</Box>
<Box mt={1} className={classes.fontText}>
26 South Hawthorne Drive Tonawanda, NY 14150
</Box>
<Box mt={1}>
<QRCode size={80} value={"4234432"} />
</Box>
</Grid>
</Grid>
</Box>
);
};
export default SampleCard;
Watch out for the comments in your return statement. (I don't know if they will break your application)
You can do that by changing the structure a little
Add a root class to hold the main box
root: {
width: "8.5cm",
height: "5.5cm",
border: "3px solid #000000",
borderRadius: "3px",
boxSizing: "border-box"
},
Remove the border from the container class
container: {
color: "#00000",
height: "100%"
},
Apply it to the parent element
<Box className={classes.root} m={3}>
Add the centered text
<Box mb={1} className={classes.fontText} align="center">
Hello John Joseph Jones
</Box>
Take a look at https://codesandbox.io/s/material-ui-forked-dvoun?file=/SampleCard.js:197-252
In the example above I add some padding to the parent element, as now it holds the border, there may be other ways of doing that to keep the style
To keep the fixed size you will need to play around with the elements

How do align content to the center in flexbox

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

Resources