0

I am new to CSS and I am trying to get my home button to work. It seems like the CSS for the home button is conflicting with the code for the other buttons. My CSS for the button is at the bottom of this code and I kept the rest incase I missed something that could possibly conflict with the button:

.game {
  min-height: 100vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: lightblue;
  h1 {
    text-align: center;
    display: block;
    margin: 2rem;
    font-family: "Caveat", cursive;
    font-size: 3rem;
  }
  h2 {
    margin: 1rem;
  }
  img {
    width: 10%;
    border-radius: 20px;
    border: 5px solid black;
    margin: 1rem;
  }
}

.main-body {
  font-family: "Lato", sans-serif;
  text-align: center;
}

//Temporary style. Will need to do this properly later

body {
  text-align: center;
  font-family: -apple-system, sans-serif;
}
.container {
  width: 1060px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 20px;
}
button {
  background-color: rgb(64, 154, 184);
  border: none;
  color: white;
  padding: 15px 32px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  border-radius: 25px;
  outline: none;
  margin: 2rem;
  transition: 0.3s ease-in-out;
  cursor: pointer;
  &:hover {
    background: rgb(47, 120, 144);
  }
}
button:focus {
  outline: 0;
}
#cards {
  width: 1060px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
}
.card {
  width: 160px;
  height: 160px;
  margin-bottom: 20px;
}
.card:not(:nth-child(6n)) {
  margin-right: 20px;
}

.c {
  position: absolute;
  max-width: 160px;
  max-height: 160px;
  width: 50ch;
  height: 50ch;
  cursor: pointer;
  will-change: transform, opacity;
}

.front,
.back {
  background-size: cover;
}

.back {
  background-image: url("../img/CardBackBlue.png");
  border: 5px solid rgb(58, 138, 165);
  border-radius: 20px;
}

.front {
  border: 5px solid rgb(58, 138, 165);
  border-radius: 20px;
}

.home-button1 {
  .home-button {
    margin: 1rem;
    border: none;
    height: 4rem;
    width: 4rem;
    position: absolute;
    top: 0;
    right: 0;
    background: lightblue;
    outline: none;
    padding: auto;
    cursor: pointer;
    & :hover {
      background: rgb(83, 147, 168);
    }
  }
  .home-pic {
    margin: auto;
    width: 90%;
    border: none;
  }
}

Here is the HTML:

// import React from "react";
import React, { useState, useEffect } from "react";
import { useSpring, animated as a } from "react-spring";
import HomeButton from "../img/home-button.svg";
import Background1 from "../img/cartoon-animals/card-1.png";
import Background13 from "../img/cartoon-animals/card-13.png";
import Background3 from "../img/cartoon-animals/card-3.png";
import Background4 from "../img/cartoon-animals/card-4.png";
import Background5 from "../img/cartoon-animals/card-5.png";
import Background6 from "../img/cartoon-animals/card-6.png";
import Background7 from "../img/cartoon-animals/card-7.png";
import Background8 from "../img/cartoon-animals/card-8.png";
import Background9 from "../img/cartoon-animals/card-9.png";
import Background14 from "../img/cartoon-animals/card-14.png";
import Background11 from "../img/cartoon-animals/card-11.png";
import Background12 from "../img/cartoon-animals/card-12.png";

export default function Game({ setPageStatus, pageStatus }) {
  const [options, setOptions] = useState(null);
  const [highScore, setHighScore] = useState(0);

  //This will check to see if new score is high score
  useEffect(() => {
    const json = localStorage.getItem("memorygamehighscore");
    const savedScore = JSON.parse(json);
    if (savedScore) {
      setHighScore(savedScore);
    }
  }, []);

  return (
    <div className={`game ${pageStatus ? "active-game" : ""}`}>
      <div className="home-button1">
        <button onClick={() => setPageStatus(0)} class="home-button">
          <img className="home-pic" src={HomeButton} alt="Home Button" />
        </button>
      </div>
      <h1>EduMemory</h1>

      <h2>Memory Game</h2>

      <div className="container">
        <div>
          <h4>High Score: {highScore}</h4>
        </div>
        <div>
          {options === null ? (
            <>
              <button onClick={() => setOptions(12)}>Easy</button>
              <button onClick={() => setOptions(18)}>Medium</button>
              <button onClick={() => setOptions(24)}>Hard</button>
            </>
          ) : (
            <>
              <button
                onClick={() => {
                  const prevOptions = options;
                  setOptions(null);
                  setTimeout(() => {
                    setOptions(prevOptions);
                  }, 5);
                }}
              >
                Start Over
              </button>
              <button onClick={() => setOptions(null)}>Main Menu</button>
            </>
          )}
        </div>
      </div>

      {options ? (
        <MemoryGame
          options={options}
          setOptions={setOptions}
          highScore={highScore}
          setHighScore={setHighScore}
        />
      ) : (
        <h2>Choose a difficulty to begin!</h2>
      )}
    </div>
  );
}

//Game Board. Put in another file
function MemoryGame({ options, setOptions, highScore, setHighScore }) {
  const [game, setGame] = useState([]);
  const [flippedCount, setFlippedCount] = useState(0);
  const [flippedIndexes, setFlippedIndexes] = useState([]);

  const colors = [
    `url(${Background1})`,
    `url(${Background13})`,
    `url(${Background3})`,
    `url(${Background4})`,
    `url(${Background5})`,
    `url(${Background6})`,
    `url(${Background7})`,
    `url(${Background8})`,
    `url(${Background9})`,
    `url(${Background14})`,
    `url(${Background11})`,
    `url(${Background12})`,
  ];

  useEffect(() => {
    const newGame = [];
    for (let i = 0; i < options / 2; i++) {
      const firstOption = {
        id: 2 * i,
        colorId: i,
        color: colors[i],
        flipped: false,
      };
      const secondOption = {
        id: 2 * i + 1,
        colorId: i,
        color: colors[i],
        flipped: false,
      };

      newGame.push(firstOption);
      newGame.push(secondOption);
    }

    const shuffledGame = newGame.sort(() => Math.random() - 0.5);
    setGame(shuffledGame);
  }, []);

  //Section that shows high score. Maybe change later as is a little confusing
  useEffect(() => {
    const finished = !game.some((card) => !card.flipped);
    if (finished && game.length > 0) {
      setTimeout(() => {
        const bestPossible = game.length;
        let multiplier;

        if (options === 12) {
          multiplier = 5;
        } else if (options === 18) {
          multiplier = 2.5;
        } else if (options === 24) {
          multiplier = 1;
        }

        const pointsLost = multiplier * (0.66 * flippedCount - bestPossible);

        let score;
        if (pointsLost < 100) {
          score = 100 - pointsLost;
        } else {
          score = 0;
        }

        if (score > highScore) {
          setHighScore(score);
          const json = JSON.stringify(score);
          localStorage.setItem("memorygamehighscore", json);
        }
        //was getting error "Unexpected use of 'confirm' no-restricted-globals". Just needed to add "window."below
        const newGame = window.confirm(
          "You Win!, SCORE: " + score + " New Game?"
        );
        if (newGame) {
          const gameLength = game.length;
          setOptions(null);
          setTimeout(() => {
            setOptions(gameLength);
          }, 5);
        } else {
          setOptions(null);
        }
      }, 500);
    }
  }, [game]);

  // Runs if two cards have been flipped
  if (flippedIndexes.length === 2) {
    const match =
      game[flippedIndexes[0]].colorId === game[flippedIndexes[1]].colorId;

    if (match) {
      const newGame = [...game];
      newGame[flippedIndexes[0]].flipped = true;
      newGame[flippedIndexes[1]].flipped = true;
      setGame(newGame);

      const newIndexes = [...flippedIndexes];
      newIndexes.push(false);
      setFlippedIndexes(newIndexes);
    } else {
      const newIndexes = [...flippedIndexes];
      newIndexes.push(true);
      setFlippedIndexes(newIndexes);
    }
  }

  if (game.length === 0) return <div>loading...</div>;
  else {
    return (
      <div id="cards">
        {game.map((card, index) => (
          <div className="card" key={index}>
            <Card
              id={index}
              color={card.color}
              game={game}
              flippedCount={flippedCount}
              setFlippedCount={setFlippedCount}
              flippedIndexes={flippedIndexes}
              setFlippedIndexes={setFlippedIndexes}
            />
          </div>
        ))}
      </div>
    );
  }
}

//Card setup. should be in a separate file eventually
function Card({
  id,
  color,
  game,
  flippedCount,
  setFlippedCount,
  flippedIndexes,
  setFlippedIndexes,
}) {
  const [flipped, set] = useState(false);
  const { transform, opacity } = useSpring({
    opacity: flipped ? 1 : 0,
    transform: `perspective(600px) rotateX(${flipped ? 180 : 0}deg)`,
    config: { mass: 5, tension: 500, friction: 80 },
  });

  //Set timer, then flip the cards back
  useEffect(() => {
    if (flippedIndexes[2] === true && flippedIndexes.indexOf(id) > -1) {
      setTimeout(() => {
        set((state) => !state);
        setFlippedCount(flippedCount + 1);
        setFlippedIndexes([]);
      }, 1000);
    } else if (flippedIndexes[2] === false && id === 0) {
      setFlippedCount(flippedCount + 1);
      setFlippedIndexes([]);
    }
  }, [flippedIndexes]);

  const onCardClick = () => {
    if (!game[id].flipped && flippedCount % 3 === 0) {
      set((state) => !state);
      setFlippedCount(flippedCount + 1);
      const newIndexes = [...flippedIndexes];
      newIndexes.push(id);
      setFlippedIndexes(newIndexes);
    } else if (
      flippedCount % 3 === 1 &&
      !game[id].flipped &&
      flippedIndexes.indexOf(id) < 0
    ) {
      set((state) => !state);
      setFlippedCount(flippedCount + 1);
      const newIndexes = [...flippedIndexes];
      newIndexes.push(id);
      setFlippedIndexes(newIndexes);
    }
  };

  return (
    <div onClick={onCardClick}>
      <a.div
        className="c back"
        style={{
          opacity: opacity.interpolate((o) => 1 - o),
          transform,
        }}
      />
      <a.div
        className="c front"
        style={{
          opacity,
          transform: transform.interpolate((t) => `${t} rotateX(180deg)`),
          backgroundImage: color,
        }}
      />
    </div>
  );
}

//export default Game;
EduDev
  • 33
  • 9
  • Hello I would advise you to use vanilla css and not scss from the beginning to better understand what the browser actually reads. Right now in your styles you select all elements with the class home-button which are nested in an element with the class home-button1 – DavLin Jan 16 '21 at 07:26
  • I removed the .home-button1, The button does seem to be working but it is the picture inside that doesn't show up. – EduDev Jan 18 '21 at 01:12
  • Does the alternative text show up? Also check you're using className not class on your button – DavLin Jan 19 '21 at 10:24

0 Answers0