Search code examples
javascriptcssnpmweb-deploymentfirebase-hosting

Animations stop working after building and deploying to Firebase


I'm having a problem where my animations stop working once I npm run-script build and firebase deploy my react app to Firebase hosting.

No idea why this is happening, I've added every web browser compatible keyframes.

Here's what my app looks like when ran on localhost (npm start):

enter image description here

And then what it looks like hosted from firebase:

enter image description here

It's like it can't read my keyframe animations.

Here's index.js:

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware, compose, combineReducers } from "redux";
import thunk from "redux-thunk";
import * as serviceWorker from "./serviceWorker";
import userReducer from "./store/reducers/user";

import { WithClass } from "./hoc/WithClass";
import classes from "./index.module.css";
import App from "./App";

// Icons made by Freepik from www.flaticon.com

// Reducers
const rootReducer = combineReducers({
  user: userReducer,
});

// Store
const store = createStore(rootReducer, applyMiddleware(thunk));

const app = (
  <Provider store={store}>
    <WithClass>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </WithClass>
  </Provider>
);

ReactDOM.render(app, document.getElementById("root"));

App.js:

import React from "react";
import { Route, Switch, withRouter, Redirect } from "react-router-dom";

import HomePage from "./pages/HomePage/HomePage";
import AboutPage from "./pages/AboutPage/AboutPage";
import WorkPage from "./pages/WorkPage/WorkPage";
import PhotographyPage from "./pages/PhotographyPage/PhotographyPage";
import ContactPage from "./pages/ContactPage/ContactPage";
import { WithClass } from "./hoc/WithClass";

/**
 * Contains switch routing to components
 *
 * Called by index.js in ReactDOM.render()
 */
const App = () => {
  return (
    <WithClass>
      <Switch>
        <Route path="/about" exact component={AboutPage} />
        <Route path="/work" exact component={WorkPage} />
        <Route path="/photography" exact component={PhotographyPage} />
        <Route path="/contact" exact component={ContactPage} />
        <Route path="/" exact component={HomePage} />
        <Redirect to="/" />
        {/* Redirect anything other than routes specified to "/" */}
      </Switch>
    </WithClass>
  );
};

export default withRouter(App);

HomePage.js:

import React, { useEffect } from "react";
import AnimatedSlideShowText from "../../components/UI/AnimatedSlideShowText/AnimatedSlideShowText";
import HeaderAnimated from "../../components/UI/HeaderAnimated/HeaderAnimated";
import HeaderStatic from "../../components/UI/HeaderStatic/HeaderStatic";
import SocialMediaFooter from "../../components/UI/SocialMediaFooter/SocialMediaFooter";
import { useDispatch, useSelector } from "react-redux";
import { loadedOnce } from "../../store/actions/user";

import classes from "./HomePage.module.css";

const HomePage = () => {
  const dispatch = useDispatch();
  const didLoadOnce = useSelector((state) => state.user.loadedOnce);

  useEffect(() => {
    setTimeout(() => {
      dispatch(loadedOnce());
    }, 2000);
  }, []);

  return (
    <div className={classes.MainContainer}>
      <div className={classes.HeaderContainer}>
        {didLoadOnce ? <HeaderStatic /> : <HeaderAnimated />}
      </div>
      <div className={classes.BodyContainer}>
        <div className={classes.NameContainer}>
          <AnimatedSlideShowText tag="h1">
            Christian Nicoletti
          </AnimatedSlideShowText>
          <AnimatedSlideShowText
            tag="h2"
            mainTextStyle={classes.Title}
          >
            Software Engineer
          </AnimatedSlideShowText>
          <AnimatedSlideShowText
            tag="h3"
            mainTextStyle={classes.School}
          >
            University of California, Santa Cruz graduate
          </AnimatedSlideShowText>
        </div>
        <div className={classes.FooterContainer}>
          <SocialMediaFooter />
        </div>
      </div>
    </div>
  );
};

export default HomePage;

HomePage.module.css:

.MainContainer {
  width: 100vw;
  height: 100vh;
  min-width: 1500px;
}

.BodyContainer {
  display: flex;
  height: 100%;
  justify-content: center;
  margin-left: 20%;
  flex-direction: column;
}

.NameContainer {
  display: flex;
  height: 250px;
  width: 500px;
}

.Title {
  margin-top: 60px;
  -webkit-animation-delay: 0.2s;
  animation-delay: 0.2s;
}

.School {
  margin-top: 120px;
  -webkit-animation-delay: 0.3s;
  animation-delay: 0.3s;
}

.HeaderContainer {
  position: absolute;
  right: 100px;
}

.FooterContainer {
  width: 500px;
}

AnimatedSlideShowText.js:

import React from "react";
import classes from "./AnimatedSlideShowText.module.css";

const AnimatedSlideShowText = (props) => {
  const CustomTag = `${props.tag}`;
  return (
    <CustomTag className={`${classes.MainText} ${props.mainTextStyle}`}>
      {props.children}
    </CustomTag>
  );
};

export default AnimatedSlideShowText;

AnimatedSlideShowText.module.css:

.MainText {
  color: white;
  position: absolute;
  opacity: 0;
  margin-left: -10%;
  font-family: Calibri;
  font-weight: 300;
  -webkit-animation: slide 0.5s forwards;
  animation: slide 0.5s forwards;
}

@-o-keyframes slide {
  100% {
    margin-left: 0%;
    opacity: 100%;
  }
}

@-ms-keyframes slide {
  100% {
    margin-left: 0%;
    opacity: 100%;
  }
}

@-moz-keyframes slide {
  100% {
    margin-left: 0%;
    opacity: 100%;
  }
}

@-webkit-keyframes slide {
  100% {
    margin-left: 0%;
    opacity: 100%;
  }
}

@keyframes slide {
  100% {
    margin-left: 0%;
    opacity: 100%;
  }
}

@-webkit-keyframes show {
  /* Chrome, Safari */
  0% {
    width: 100%;
  }
  100% {
    width: 0%;
  }
}
@-moz-keyframes show {
  /* FF */
  0% {
    width: 100%;
  }
  100% {
    width: 0%;
  }
}
@-ms-keyframes show {
  /* IE10 */
  0% {
    width: 100%;
  }
  100% {
    width: 0%;
  }
}
@-o-keyframes show {
  /* Opera */
  0% {
    width: 100%;
  }
  100% {
    width: 0%;
  }
}
@keyframes show {
  0% {
    width: 100%;
  }
  100% {
    width: 0%;
  }
}

I'd add more component source code, but I think AnimatedSlideShowText is all that is needed to understand the problem.

So again, I'm just trying to get my animations to work when built and deployed. I'm not sure why they would stop working when built and deployed.

Is it possible that using module.css has an impact on animations when built/deployed? Any help would be super appreciated, and if you need more source code let me know.


Solution

  • Ok so! I managed to fix it. I thought this was a lot more complex than it actually was.

    Short answer: I had to change all my opacity: 100% to opacity: 1 and suddenly everything appeared and worked correctly.

    Long answer: I had to dabble in the console for a bit, and realized that all my components and text were there, but just not showing up. I played with the animations by disabling and re-enabling, and stuff would flicker for a second. I realized that it was rendering the opacity as: opacity: 1% instead of opacity: 100%. Apparently, when building with npm run-script build, it acts as if 100% has trailing zeros(??).

    Anyway, I appreciate the help, and everything works perfectly now.