Set background image to full screen in Reactjs - reactjs

I'm trying to set a background image in React but it only covers about 75% of the height.
It seems that the component doesn't take up all of the height.
What's the solution?
In index.js:
ReactDOM.render(<Login />, document.getElementById('root'));
In index.css:
html, body, .Login-component {
height: 100%;
}
In Login.js:
render() {
return (
<div className='Login-component'>
);
}
In Login.css
.Login-component {
background: url(../static/login-bg.jpg) no-repeat center center fixed;
background-size: cover;
}
The end result: Screen shot

Use vh and vw properties:
const styles = {
container: {
backgroundImage: `url(${backgroundImage})`,
backgroundPosition: 'center',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
width: '100vw',
height: '100vh'
}
};

Try using the specific property values.
In Index.css:
body, html {
height: 100%;
margin: 0;
}
In Login.css:
.Login-component {
/* The image used */
background-image: url(../static/login-bg.jpg);
/* Full height */
height: 100%;
/* Center and scale the image nicely */
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}

The image should be inside your src folder besides that, inside your component you do the following.-
const imgMyimageexample = require('../assets/imageexample.jpg');
const divStyle = {
width: '88%',
height: '800px',
backgroundImage: `url(${imgMyimageexample})`,
backgroundSize: 'cover' <---- This is important
};
export default class Mycomponent extends React.Component {
render() {
return (
<div className="cComponent" style={divStyle} >
<h1 align="center">Some header example</h1>
</div>
);
}
}

While it is hard to troubleshoot without any code, check the root element to which your react component is being rendered to. Setting height: '100%' in the style of your component will be in the context of it's parent div.

Edit the CSS.
This might be what you are looking for:
<Component style={{ minHeight: '100%' }} />
If you meant that the background image is not covering the whole height, then add a className to your component, import the CSS where you'll do something like this

An answer by Jorge Carretero is helpful and in case it still doesn't work for you, try adding default
const imgMyimageexample = require('../assets/imageexample.jpg').default;
const divStyle = {
backgroundImage: `url(${imgMyimageexample})`,
backgroundSize: 'cover' <---- This is important
};

Full typescript solution:
import imgBG from "../assets/imgBG.jpg";
interface imgStyleType {
backgroundImage: string;
backgroundPosition: string;
backgroundSize: string;
backgroundRepeat: string;
width: string;
height: string;
}
const imgStyle: imgStyleType = {
backgroundImage: `url(${imgBG})`,
backgroundPosition: "center",
backgroundSize: "cover",
backgroundRepeat: "no-repeat",
width: "100vw",
height: "100vh",
};
export default function ImgBG() {
return (
<>
<div style={imgStyle} />
</>
);
}

.Login-component{
background-image:url(path) ;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
height: 100vh;
}

Related

How to stop propagation of scroll event in case of a modal view?

I have this modal React component:
import React, { useEffect, useRef } from 'react'
import useOnClickOutside from '../../hooks/useOnClickOutside'
import Button from '../codrop/Button'
import styles from './Modal.module.scss'
var Scroll = require('react-scroll')
var scroll = Scroll.animateScroll
interface Props {
children?: React.ReactNode
title?: string
completion?: Function
[key: string]: any
isMyFlex?: Boolean
}
const Modal = ({ children, title, completion, isMyFlex, ...rest }: Props) => {
return (
<div className="overlay">
<div className="cnt-box cnt-call2 modal">
<div className="caption" style={{ paddingRight: 'unset' }}>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
}}
>
<h2 style={{ fontSize: '30px', fontWeight: '500' }}>{title}</h2>
<span
onClick={(e) => {
completion?.()
}}
style={{
fontFamily: 'Icons',
fontSize: '2rem',
cursor: 'pointer',
}}
>
c
</span>
</div>
{children}
</div>
</div>
</div>
)
}
export default Modal
And following two style:
.overlay {
position: fixed; /* Sit on top of the page content */
width: 100%; /* Full width (cover the whole page) */
height: 100%; /* Full height (cover the whole page) */
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5); /* Black background with opacity */
z-index: 2000; /* Specify a stack order in case you're using a different order for other elements */
overflow: hidden;
}
.modal {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 470px;
background-color: #fff;
border-radius: 6px;
padding: 30px 50px;
}
When modal / overlay is present, and I scroll in mobil, I see on the bottom, as some pixlel is visilbe from background, that the background i scrolling, though not the foreground.
Is it a way to prevent this scrolling?
I tried to add overflow: hidden; to the overlay style, did not help.
I tried hide overflow when component appears, but has no effect, why?
const Modal = ({ children, title, completion, isMyFlex, ...rest }: Props) => {
useEffect(() => {
document.body.style.overflow = 'hidden'
return () => {
document.body.style.overflow = 'unset'
}
}, [])
By default, trying to scroll an element that has already reached the bottom will scroll the parent. You can use the overscroll-behavior CSS property on the modal to prevent this behavior:
overscroll-behavior: contain;
See https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior for the documentation.

Button doesn't disappear immediately; need to move mouse during animation using clip-path

I am setting the clipPath property from circle(0%) to circle(100%) using GSAP timeline.
let t1 = useRef();
useEffect(() => {
t1.current = gsap.timeline({
defaults: { duration: 0.5, ease: "Back.easeOut.config(2)" },
});
t1.current.paused(true); //to ensure animation doesn't play immediately
t1.current.to(".overlay", { clipPath: "circle(100%)" });
});
const handleClick = () => {
t1.current.play(); //start the animation
};
const handleClose = () => {
t1.current.reverse(0.2); //reverse the animation from 0.2 seconds
};
Complete React Component code:
import React, { useEffect, useRef } from "react";
import { gsap } from "gsap";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faWindowClose } from "#fortawesome/free-solid-svg-icons";
export default function GSAPFullScreen() {
let t1 = useRef();
useEffect(() => {
t1.current = gsap.timeline({
defaults: { duration: 0.5, ease: "Back.easeOut.config(2)" },
});
t1.current.paused(true); //to ensure animation doesn't play immediately
t1.current.to(".overlay", { clipPath: "circle(100%)" });
}, []);
const handleClick = () => {
t1.current.play(); //start the animation
};
const handleClose = () => {
t1.current.reverse(0.2); //reverse the animation from 0.2 seconds
};
return (
<>
<div
className="overlay"
style={{
clipPath: "circle(0%)",
width: "100%",
height: "100%",
position: "fixed",
overflowY: "scroll",
overflowX: "hidden",
backgroundColor: "purple",
}}
>
<FontAwesomeIcon
icon={faWindowClose}
size="2x"
style={{
position: "absolute",
top: "2rem",
right: "2rem",
color: "white",
cursor: "pointer",
}}
onClick={handleClose}
/>
<div className="container md" style={{ color: "white" }}>
<br />
<div style={{ fontWeight: "bold" }}>This is an amazing Question</div>
<div>What is your question? Can you guess?</div>
<div>Option 1</div>
<div>Option 2</div>
<div>Option 3</div>
<div>Option 4</div>
</div>
</div>
<div className="container" style={{ height: "100vh" }}>
<div className="flex">
<button className="lg p-1 btn" onClick={() => handleClick()}>
Launch Animation
</button>
</div>
</div>
</>
);
}
Relevant CSS:
.container {
max-width: 1100px; /* Ensures heading is in center beyond 1100px*/
margin: 0 auto; /* Ensures to keep the 1100px container in middle of the screen;
until 1100px it will be on the side and this property will not have any affect*/
overflow: auto; /* This removes the space on the top of the heading which was created because of margin: 10px 0 on h1*/
padding: 0 40px;
}
.btn {
display: inline-block;
padding: 10px 30px;
cursor: pointer;
background: var(--primary-color);
color: #fff;
border: none;
border-radius: 5px;
}
.md {
font-size: 2rem;
}
.lg {
font-size: 3rem;
}
.flex {
display: flex;
justify-content: center; /* aligns along the main axis*/
align-items: center;
height: 100%;
}
.p-1 {
padding: 1rem; /*1 rem is usually 16px depending the size at root*/
}
.btn:hover:enabled{
transform: scale(0.98); /*reduces the size of button a bit*/
}
When the button has the pseudo class :hover a transform will be applied to the element, which means that it the stacking context is changed (see also Stacking without the z-index property).
To fix this you can add z-index: 1 to the overlay class or remove the transform from the :hover class (Not ideal).

My Google Maps is not taking my footer CSS

I am trying to make sure that any CSS I put within my Footer is not affected by adding my Google Maps API. You can see from the example that I am not able to keep the back ground black.
Footer
import React, {Component} from 'react';
import { Map, Marker, GoogleApiWrapper } from 'google-maps-react';
import './App.css';
class Footer extends Component {
render(){
const style = {
width: '300px',
height: '300px',
backgroundColor: 'black'
}
return (
<div className="site-footer">
<footer>
<p>My Footer</p>
<Map
google={this.props.google}
zoom={10}
initialCenter={{
lat: 35.5496939,
lng: -120.7060049
}}
style={style}
/>
</footer>
</div>
)
}
}
export default GoogleApiWrapper({
apiKey: ('YOUR_API_KEY')
})(Footer);
Footer CSS
.site-footer {
left: 0;
bottom: 0;
width: 100%;
margin-top: 20px;
color: white;
text-align: center;
flex-shrink: 0;
background: black;
}
Footer Example
It seems that there are different divs that contains the map when using the google-maps-react library. Per the package's documentation there's a style - which you configure to set the map dimension and there's a containerStyle - which is a div that contains the map.
So to set the map background to black, you need to use the containerStyle.
class Footer extends Component {
render(){
const style = {
width: '300px',
height: '300px'
}
const containerStyle = {
position: 'absolute',
width: '100%',
height: '100%',
backgroundColor: 'black'
}
return (
<div className="site-footer">
<footer>
<p>My Footer</p>
<Map
google={this.props.google}
zoom={10}
initialCenter={{
lat: 35.5496939,
lng: -120.7060049
}}
style={style}
containerStyle={containerStyle}
/>
</footer>
</div>
)
}
}
export default GoogleApiWrapper({
apiKey: "YOUR_API_KEY"
})(Footer);
You would also need to define the width and height of your site-footer class to fill in the white spaces. I used 800px here so that it will really fully contain my map and its container.
.site-footer {
left: 0;
bottom: 0;
width: 800px;
height: 800px;
margin-top: 20px;
color: white;
text-align: center;
flex-shrink: 0;
background-color: black;
}
Please see sample code.
Please use your API key in the sample code for it to work.

Adjusting toolbar height for material-table

The blue marked area takes up a lot of space. How can I adjust the height of the Toolbar?
Can you show by example?
Or how can I create a css file and import it into the toolbar. I need to change the height, I couldn't change whatever I did. please can you help with this?
There is almost no method I have not tried.
In short, I want to adjust the height of the Mtabletoolbar field marked in blue.
<MaterialTable
Toolbar: props => (
<div style={{ backgroundColor: 'blue', }}>
<MTableToolbar {...props} classes={{ customizeToolbar: "15px" }} />
</div>
),
/>
`
const styles = {
customizeToolbar: {
minHeight: "100px"
}
}
`
I have been trying for 2 days, please can you help with the subject?
I need to change the style structure below. especially I have to change the min-height
.MuiToolbar-regular {
min-height: 64px;
}
`
.MuiToolbar-root {
display: flex;
position: relative;
align-items: center;
}
.MuiToolbar-regular {
min-height: 56px;
}
#media (min-width:0px) and (orientation: landscape) {
.MuiToolbar-regular {
min-height: 48px;
}
}
#media (min-width:600px) {
.MuiToolbar-regular {
min-height: 64px;
}
}
.MuiToolbar-dense {
min-height: 48px;
}
`
Simply adjust the style of the element where blue appears,
and make the child vertical center as below:
<div
style={{
backgroundColor: "lightblue",
height: "200px",
display: "flex",
alignItems: "center"
}}
>
<MTableToolbar {...props} />
</div>

Transitions with React - should I use TransitionGroup?

I want page contents in my application to transition smoothly. I have been attempting to do this using react-transition-group but I have struggled to achieve the correct implementation. The following link was informative:
https://coursework.vschool.io/react-transitions-with-react-transition-group/
It shows how to make modularize and use TransitionGroup (although not both at the same time, unfortunately).
I created a demo project (based on the above link) to troubleshoot this issue. I have two items in an array ‘contactComponents’. All I am trying to do at the moment is make this information appear and disappear using the show/hide button.
Here is the main body of the code:
const contactDetails = ['Gryffindor Tower, Hogwarts','Gryffindor Tower, Hogwarts'];
const contacts = ['Harry', 'Ron'];
export default class App extends React.Component {
constructor(props){
super(props);
this.state = {
count: 0,
showMyContact: false
};
this.showContact = this.showContact.bind(this);
}
showContact() {
this.setState({showMyContact: !this.state.showMyContact})
}
render() {
const styles = {
container: { display: 'flex', justifyContent: 'center', width: '100vw', height: 100, flexDirection: 'column', padding: 100 },
btn: { width: '100%', display: 'flex', justifyContent: 'center'},
h1: { border: '2px solid blue', padding: 5, display: 'flex'}
};
let contactComponents = [contacts[this.state.count], contactDetails[this.state.count]];
console.log(this.state.showMyContact)
return (
<div>
<div style={ styles.container }>
<TransitionGroup component={null}>
{ contactComponents.map((item, key) =>
<CSSTransition
in={this.state.showMyContact}
key={key}
timeout={800}
classNames={"fade"}>
<h1 style={styles.h1}>
{
item
}
</h1>
</CSSTransition>
)}
</TransitionGroup>
<div style={ styles.btn }>
<button onClick={ this.showContact }>show/hide</button>
</div>
</div>
</div>
)
}
}
scss file:
.fade-appear,
.fade-enter {
opacity: 0;
z-index: 1;
}
.fade-appear-active,
.fade-enter.fade-enter-active {
opacity: 1;
transition: opacity 600ms linear 200ms;
}
.fade-exit {
opacity: 1;
}
.fade-exit.fade-exit-active {
opacity: 0;
transition: opacity 200ms linear;
}
Currently, the contents appears even though showMyContact is false when the render function first calls. Changing the state of showMyContact with the show/hide button has no effect. The content does not fade in and out as expected.
This post:
page transitions without React-Router
suggests it might be better to use pure css to carry out transitions rather than react-transition-group. Am I just barking up the wrong tree?
I found out that using pure css transitions provides the desired solution. I do not know if a solution using TransitionGroup and CSSTransition is feasible but it doesn't look like it.
By changing the contents of the render function to:
render() {
let contactComponents = [contacts[this.state.count], contactDetails[this.state.count]];
let cssList = [
"List",
this.state.showMyContact ? "ListShow" : "ListHide"
];
console.log(this.state.showMyContact);
return (
<div>
<div className={"container"}>
<List show={cssList.join(' ')} myContent={contactComponents}/>
<div className={"btn"}>
<button onClick={ this.showContact }>show/hide</button>
</div>
</div>
</div>
)
}
...and adding the following const:
const List = (props) => {
return (
<div className={props.show}>
<h1 className={"h1"}> { props.myContent[0] } </h1>
<h1 className={"h1"}> { props.myContent[1] } </h1>
</div>
)};
...and importing the following css file:
.container {
display: flex;
justify-content: center;
width: 500px;
height: 100px;
flex-direction: column;
padding: 100px;
}
.h1 {
border: 2px solid blue;
padding: 5px;
display: flex;
}
.btn {
width: 100%;
display: flex;
justify-content: center;
}
.List {
display: flex;
flex-direction: column;
transition: all 0.4s ease-out;
}
.ListShow {
opacity: 1;
}
.ListHide {
opacity: 0;
}
...I can get the desired behaviour.

Resources