React Inline BackgroundImage with Media Queries - reactjs

I am working on a react app that is responsive. When the viewport shrinks or increases the 'backgroundImage' should change. I used an inline style because I was unable to use a relative path to the image which is in the public folder.
I have created a media queries within a variable in react with the widths that they should change.
I have placed the style within the .hearder-flex dive element.
Header.js
const Header = () => {
const media = {
'#media (max-width: 650px)':{
backgroundImage: 'url("starter-code/assets/mobile/bg-pattern-header.svg")' ,
},
'#media (min-width: 750px)':{
backgroundImage: 'url("starter-code/assets/tablet/bg-pattern-header.svg")' ,
}
}
return (
<div className="header-wrapper">
<main className="header-flex" style={media}>
<img src="starter-code/assets/desktop/logo.svg" alt="logo" className="logo-img"/>
<div class="space-around">
<img src="starter-code/assets/desktop/icon-sun.svg" alt="icon-sun" className="sun-img"/>
<label className="switch">
<input type="checkbox" />
<span className="slider"/>
</label>
<img src="starter-code/assets/desktop/icon-moon.svg" alt="icon-moon" className="moon-img"/>
</div>
</main>
<div className="input-search">
<img src="starter-code/assets/desktop/icon-search.svg" alt="icon-search" className="icon-search"/>
<input type="text" placeholder="Enter desired job..." className="enter-job"/>
</div>
</div>
);
}
export default Header;

well, Media Queries cannot be used as the inline style.
However you can use this approach to assign the background images:
First create the css style as below and save it in a variable called css:
const css = `#media (max-width: 650px) {
.backimage {
background-image: url("https://picsum.photos/200/300")
}
}
#media (min-width: 750px) {
.backimage {
background-image: url("https://picsum.photos/200");
}
}`;
Then, use it in the component in the style tag above the main tag:
<style scoped>{css}</style>
<main style={{ height: 300 }} className="backimage">
Please also check this sandbox link

Related

React - Modal expands div in footer div not on main screen

New to coding, trying to get a modal to work. It is not opening the way I expected it to.
The component is currently loaded within the footer div of my site. And when the button is toggled it simply hides or shows a div within the footer. I want it to appear in the centre of the webpage as a modal.
import React, {useState} from 'react';
import './policy.css'
export default function Policy() {
const [modal, setModal] = useState(false);
const toggleModal = () => {
setModal(!modal);
};
if(modal) {
document.body.classList.add('active-modal')
} else {
document.body.classList.remove('active-modal')
}
return (
<>
<div>
<button onClick={toggleModal} className='btn-modal'>
<p>Privacy Policy</p>
</button>
</div>
{modal && (
<div className="modal">
<div onClick={toggleModal} className="overlay"></div>
<div className="modal-content">
<h2>Privacy Policy</h2>
<p>This is the privacy policy</p>
<button className='close-modal' onClick={toggleModal}>Close</button>
</div>
</div>
)}
</>
);
}
The simplest way to achieve a modal effect is to use some CSS.
You could try a very crude style like (from MUI Modal docs):
const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "lightgrey",
border: "2px solid #000",
boxShadow: 24,
padding: 4,
};
Then apply it to your modal:
<div className="modal" style={style}>

How to make the Swiper.js and React Player carousel responsive

I have been looking for a way to make my Swiper.js carousel responsive when it's nesting the Youtube React Player. I finally found a workaround and hope this helps somebody. This also works if the slidesPerView is more than 2 or even float number like slidesPerView={1.3}.
Remove the default css mySwiper class, and apply player-wrapper and react-player css as below.
The point is that the player-wrapper div is self close and does not wrap the <ReactPlayer> component. Also have the width and height props to be 100% in the <ReactPlayer> component.
<Swiper
slidesPerView={1.3}
grabCursor={false}
loop={false}
watchSlidesProgress={true}
centeredSlides={true}
modules={[Pagination, Navigation]}
// className='mySwiper' <=remove
>
<SwiperSlide>
<div className='player-wrapper' /> //<= self close div
<ReactPlayer
url='youtube.com/1234'
controls={true}
width='100%'
height='100%'
playing={isPlaying === data.id}
config={{
youtube: {
playerVars: { showinfo: 1 },
},
}}
className='react-player'
/>
</SwiperSlide>
CSS
.player-wrapper {
position: relative;
padding-top: 56.25%
}
.react-player {
position: absolute;
top: 0;
left: 0;
}

Background image with JS React and Semantic-ui

Hei
Trying to get my page to display an image that is behind the text and icons.
Here is what I have currently:
import React from 'react';
import SamplePicture from '../../images/sample-picture.jpg';
class Front extends React.Component {
render() {
return (
<div className="ui segment">
<img className="ui floated image" src={SamplePicture} />
<p>
This is a front page that will have an image in the background
<br />
Sampletext
</p>
</div>
);
}
}
export default Front;
It displays the image but the text gets rendered below.
Basicly I want to create text that gets rendered on top of the image.
First time asking a question here so maybe there is some information that I should have shared, but haven't. Anyway, be harsh, tell me what is wrong about the code, the question.
You can do something like this using flexbox:
<div className="ui segment">
<div className="ui medium image">
<div
className="ui active center"
style={{
display: 'flex',
position: 'absolute',
width: '100%',
height: '100%',
justifyContent: 'center',
zIndex: 1,
}}>
<div className="content">Sampletext</div>
</div>
<img
src="https://via.placeholder.com/410x210"
className="ui floated image"
alt="alt"
/>
</div>
</div>
This solution uses flexbox to center the text over the image.
I've used via.placeholder.com as an image source to make it easy to demo, but you can change it to your image's src.
If the text isn't exactly centered, either change your container to a smaller size (from medium to small for example) or choose a bigger (wider) image.

Can't select child-elements in chrome dev tools anymore when using an image overlay (card-img-overlay)

When using bootstrap's card-img-overlay class, I can't inspect child elements anymore using the chrome devtools. E.g. in the screenshot below, I am not able to select any of the headers anymore.
Am I using the class in a wrong way?
import React from "react"
import Layout from "../components/layout"
import { graphql } from "gatsby"
import SEO from "../components/seo"
import Img from "gatsby-image"
import Card from "react-bootstrap/Card"
import TimeToRead from "../components/time-to-read"
import Tags from "../components/tags"
const SinglePost = ({ data, pageContext }) => {
const { frontmatter } = data.markdownRemark
const { timeToRead } = data.markdownRemark
return (
<Layout pageTitle={frontmatter.title}>
<SEO title={frontmatter.title} />
<Card>
<Img
className="card-image-top"
style={{ maxHeight: "150px" }}
fluid={frontmatter.image.childImageSharp.fluid}
/>
<div className="card-img-overlay">
<Tags tags={frontmatter.tags} />
</div>
<Card.Body>
<Card.Title>{frontmatter.title}</Card.Title>
<Card.Subtitle>
<div className="d-flex justify-content-between">
<span className="text-info">{frontmatter.date}</span>
<TimeToRead minutes={timeToRead} />
</div>
<hr />
</Card.Subtitle>
<Card.Text
dangerouslySetInnerHTML={{ __html: data.markdownRemark.html }}
></Card.Text>
</Card.Body>
</Card>
</Layout>
)
}
Seem like, you can't access to the elements (and your users could not select the text) because the card-img-overlay is covering it. I have to say that this is how overlays should work. But if you need to prevent it anyway, you can use pointer-events: none.
Pay attention, when you do this, it blocks the events from all of its children too (In Chrome at least) so you need to enable it for the children.
.parent {
position: relative;
}
.overlay {
background: rgba(0, 0, 0, 0.2);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.overlay * {
pointer-events: all;
}
<div class="parent">
<div class="overlay">
<button>Click</button>
</div>
<p>text text</p>
<p>text text</p>
<p>text text</p>
<p>text text</p>
<p>text text</p>
<p>text text</p>
<p>text text</p>
<p>text text</p>
<p>text text</p>
</div>
https://jsbin.com/bariyipoha/1/edit?html,css,output

Add Space Between Row Elements in React BootStrap

I am new to React and react-bootstrap. I have a Row component and would like spacing between the top of the screen and also between the individual row elements. I am currently just editing its CSS but heard that it may be bad to mess with the CSS of frameworks?
const Styles = styled.div`
.background {
background: url(${backgroundImage}) no-repeat fixed bottom;
background-size: cover;
height: 100vh;
position: relative;
}
#row {
position: relative;
top: 200px;
}
`;
class Signup extends React.Component {
render() {
return (
<Styles>
<div className="background">
<Container>
<Row id="row" className="justify-content-md-center">
<ExtraInfo />
<SignupForm />
</Row>
</Container>
</div>
</Styles>
);
}
}
export default Signup;
Use Form.Group in React-Bootstrap. It adds 15px padding on columns to separate the content of the columns.
I'm not saying this is the best solution, but I have just created a CSS class that sets a margin attribute to 5px and then applied it to the Row element where I need it. This works for me, but I'm welcome to better answers.
For space at the top and bottom of the screen, what I have done is create a "spacer" component which I import and use to create space between elements.
I know what you mean about messing with the CSS though and this method might be a bit "hacky".
Example JSX:
<>
<p><strong>My Categories</strong></p>
{
catList.map((cat,i) => (
<Row key={i} className="add-space">
<Col><strong>Category {i+1}</strong></Col>
<Col>{cat}</Col>
<Col><Button onClick={() => removeCategory(cat)}>Remove</Button></Col>
</Row>
))
}
</>
Example CSS:
.add-space {
margin: 4px;
}
Example Spacer:
const Spacer = props => {
return (
<div style={{height:props.height}}></div>
);
}
export default Spacer;
Use:
<Spacer height="1rem" />

Resources