msbpk
msbpk

Reputation: 11

Make SVG render after loading CSS (React styled-components)

I am building a landing page with GatsbyJS and Styled-Components where I wish to display a SVG logo in the center of the screen.

After deploying to server, it appears that when loading my page, the SVG gets loaded first and immediately rendered to the upper-left corner of the screen, apparently before the CSS which makes it jumps to the center after a noticeable latency.

This is how I am doing this:

// import "styled" and React
import logo from '../images/logo.svg'

const CenterDiv = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
`
const Logo = styled.img`
  padding: 2rem;
  margin: 1rem;
  border: 1.5rem solid black;
`
const IndexPage = () => (
  <CenterDiv>
    <Logo src={logo} alt="Logo" />
  </CenterDiv>
)

export default IndexPage

How can I get the SVG loaded after the CSS, so that the users don't see the logo jump around?

I have also installed the "gatsby-plugin-styled-components" package, which let's styled-components render on server side/build-time.

Thank you!

Edit: I moved the styles to the styles prop in React components, which seems to have fixed this asynchronous issue. However, I still would like to know how to do this with styled-components, because I can write normal CSS and media queries there.

Note: In this context, I am using Gatsby/React and prefer CSS-in-JS solutions. I have similar issues when using "styled-components" in other situations too - the content gets loaded first while styles applied afterwards.

Upvotes: 1

Views: 946

Answers (1)

Rounin
Rounin

Reputation: 29463

After deploying to server, it appears that when loading my page, the SVG gets loaded first and immediately rendered to the upper-left corner of the screen, apparently before the CSS which makes it jumps to the center after a noticeable latency.

One approach would be using a CSS class to ensure that the SVG remains invisible until the window fully loads, after which it becomes visible.

E.g.

1) Add an initial class to the SVG which renders it invisible:

HTML: <svg class="logo hide">

CSS: svg.hide {opacity: 0;}


2) Then apply an onload Event Listener to the window:

window.addEventListener('load', removeOpacityFromSVG, false);

function removeOpacityFromSVG() {

    var logoSVG = document.getElementsByClassName('logo')[0];
    logoSVG.className = 'logo';
}

Upvotes: 1

Related Questions