skip to Main Content

I created a JSON file from which I create cards with different data using props in Reat.js. My issue it that I have created a custom CSS that give the card a background (covering the card content) and the on hover the background is disappearing and the content is shown. Everything works but I want to have a different background for each card, so I added in the JSON a bgImg: "imgagePath" and set a props.bgImg for the card, like this:

{
    id: 1,
    name: "Project1",
    bgImg: "filePath",
    img: "filePath",
    description:
      "Lorem, ipsum dolor sit amet consectetur adipisicing elit. Velmollitia maiores error minus, incidunt sit non placeat ipsa, veniam,nam voluptatibus? Eius a dolores minima vitae recusandae provident quos inventore!",
    projectLink: "link",
  },

my CSS for the background is:

#projectCard {
  position: relative;
  font-family: "Montserrat", sans-serif;
  width: 380px;
  height: 600px;
  overflow: hidden;
  border-radius: 20px;
}

#projectCard::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-image: url("filePath");
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 1;
  transition: opacity 1.6s ease;
  pointer-events: none;
}

#projectCard:hover::before {
  opacity: 0;
} 

while the jsx file is as follows:

import React from "react";

function ProjectCard(props) {
  return (
    <div id="projectCard">
      <div className="d-flex flex-column justify-content-between">
        <div id="imgContainer">
          <img src={props.img} alt={props.name} className="img" />
        </div>
        <h3 className="name projectName text-center">{props.name}</h3>
        <h5 className="details projectDetails">{props.details}</h5>
        <div className="d-flex justify-content-center">
          <a
            href={props.projectLink}
            className="projectButton text-decoration-none fs-1 text-primary bg-warning rounded-pill text-center px-2"
          >
            Details
          </a>
        </div>
      </div>
    </div>
  );
}

export default ProjectCard;

and then I have the other jsx file like this:

import React from "react";
import ProjectCard from "./ProjectCard";
import projects from "../projects";

function createProjectCard(project) {
  return (
    <ProjectCard
      key={project.id}
      bgImg={project.bgImg}
      img={project.img}
      name={project.name}
      details={project.description}
      projectLink={project.projectLink}
    />
  );
}

function Projects() {
  return (
    <div>
      <h1 id="projects" className="sectionTitle d-none d-xl-block">
        PROJECTS
      </h1>
      <h1
        id="projects"
        className="sectionTitleMedium d-none d-md-block d-xl-none"
      >
        PROJECTS
      </h1>
      <h1 id="projects" className="sectionTitleSmall d-block d-md-none">
        PROJECTS
      </h1>
      <div className="d-flex flex-column flex-xl-row justify-content-around align-items-center mb-5">
        {projects.map(createProjectCard)}
      </div>
    </div>
  );
}

export default Projects;

So basically, I am mapping each object so that it creates a card with with different images, descriptions, titles…

I thought of implementing CSS directly into the JSX but was unsuccessful. I thought maybe using the UseState() but not sure if that would work.

2

Answers


  1. Chosen as BEST ANSWER

    I solved the issue - the code now generates each card with a className="project + the respective id.

    import React from "react";
    
    function ProjectCard(props) {
      const className = `project project${props.id}`;
    
      return (
        <div id="projectCard" className={`${className}`}>
          <div className="d-flex flex-column justify-content-between">
            <div id="imgContainer">
              <img src={props.img} alt={props.name} className="img" />
            </div>
            <h3 className="name projectName text-center">{props.name}</h3>
            <h5 className="details projectDetails">{props.details}</h5>
            <div className="d-flex justify-content-center">
              <a
                href={props.projectLink}
                className="projectButton text-decoration-none fs-1 text-primary bg-warning rounded-pill text-center px-2"
              >
                Details
              </a>
            </div>
          </div>
        </div>
      );
    }
    
    export default ProjectCard;
    

    This way I can then apply the css (which uses ::before) for each card by using the .projectID. The CSS is tedious but it's the best solution I could think of. Open to better suggestions.


  2. for me there are two options of doing this:

    1 – Tailwind (Or another third party styling)

    2 – Inline styling

    1 – Tailwind (Add bg-[url({props.bgImg})] inside the "div" you want to add it:

    function ProjectCard(props) {
      return (
        <div id="projectCard">
          <div className="d-flex flex-column justify-content-between">
            <div id="imgContainer bg-[url(props.bgImg)]">
              <img src={props.img} alt={props.name} className="img" />
            </div>
            <h3 className="name projectName text-center">{props.name}</h3>
            <h5 className="details projectDetails">{props.details}</h5>
            <div className="d-flex justify-content-center">
              <a
                href={props.projectLink}
                className="projectButton text-decoration-none fs-1 text-primary bg-warning rounded-pill text-center px-2"
              >
                Details
              </a>
            </div>
          </div>
        </div>
      );
    }
    

    2 – Inline Styling (Add this to the div you want to add the bg Image):

    style={{ backgroundImage: `url({props.bgImg})` }}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search