I am currently working on a website, which is just a demo built in ReactJS:
The issue I'm facing is related to the background.
The idea behind the app is simple - it consists of 4 parts, with the top part displaying weather information without a background, and the other three parts each having a different background. The app needs to be mobile-friendly and responsive, as each part contains different content and therefore has varying heights.
https://i.sstatic.net/IYqqh.jpg
Now, my goal is to create a smooth transition effect between each part (weather & part 1; part 1 & part 2; part 2 & part 3) like this:
https://i.sstatic.net/UCwNu.jpg
So, I am looking for a way to stack each part slightly over the bottom of the previous part by a few pixels to blend them together seamlessly (similar to blending two PNGs in Photoshop with transparency). This effect should be achieved using CSS so that it remains consistent across all screen sizes from mobile to wide screens.
In my attempts so far, I have tried:
- Using 3 PNG images with transparency, but encountered issues due to their large file size and specific screen width display limitations.
- Adding a relative zone at the bottom/top of the component
Categorie
with alinear-gradient
, but found the rendering to be less than ideal.
1) APP.JS
import Meteo from "./components/Meteo";
import Categorie from "./components/Categorie";
function App() {
return (
<div className="App">
<h5 style={{ paddingLeft: 15 }}>Météo</h5>
<header className="App-header">
<Meteo />
<Categorie name="air" display="Air" bgpos="bottom" {/* bottomOpacity*/} />
<Categorie name="sol" display="Sol" bgpos="center" {/* bottomOpacity topOpacity*/} />
<Categorie name="eau" display="Eau" bgpos="top" {/* topOpacity */}/>
</header>
</div>
);
}
2) Categorie.js
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
leftText: {
textAlign: "left",
width: "auto",
display: "inline-block"
},
responsive: {
width: "100%",
maxWidth: "1000px",
height: "auto"
},
container: {
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center"
},
overlay: {
backgroundColor: "rgba(13,53,78, 0.6)",
color: "white",
position: "relative"
},
topOpacity: {
position: "absolute",
top: -2,
width: "100%",
height: 75,
background: "linear-gradient( to top, transparent , rgba(13,53,78,0.9 ) )",
backgroundRepeat: "no-repeat"
},
bottomOpacity: {
position: "absolute",
bottom: -2,
width: "100%",
height: 75,
background:
"linear-gradient( to bottom, transparent , rgba(13,53,78, 0.9 ) )",
backgroundRepeat: "no-repeat"
},
padding: {
padding: "auto",
paddingTop: 85,
paddingBottom: 85
}
}));
export default function Categorie(props) {
const classes = useStyles();
let ref = useRef(null);
let size = useComponentSize(ref);
let { width, height } = size;
const filename = {
air: "air.jpg",
eau: "eau.jpg",
sol: "sol.jpg"
};
let backgd = {
backgroundImage: `url('./photos/${filename[props.name]}') `,
backgroundPosition: props.bgpos || "center",
backgroundSize: "cover",
backgroundRepeat: `${width}px ${height}px`,
width: "100%"
};
return (
<div style={backgd} ref={ref}>
<div className={classes.overlay}>
{props.topOpacity && <div className={classes.topOpacity} />}
<div className={classes.padding}>
... CONTENT
</div>
{props.bottomOpacity && <div className={classes.bottomOpacity} />}
</div>
</div>
);
}