DEV Community

Cover image for CSS Logos: React logo
Chris Bongers
Chris Bongers

Posted on • Updated on • Originally published at daily-dev-tips.com

CSS Logos: React logo

I'm sure you have seen the React (atom-like) logo before, but as a reminder, this is what it looks like:

React Logo

Analysing the logo

The logo consists of three ellipses that form around a ball.

I want to challenge myself and try to create this as a single div artwork.

We should be able to use the before and after pseudo-elements to create two of the lines.
Then the main div can hold the dot and the third line.

Since this is a little bit simpler, we'll also animate the logo, so you get to experience CSS animations.

Recreating the React logo in CSS

Let's get started and create the single div element.

<div class="react"></div>
Enter fullscreen mode Exit fullscreen mode

Let's also look into an excellent concept in processed CSS called @extend I'll be using SCSS as we have a lot of recurring elements that we can quickly share between selectors.

Note: You can still use CSS, copy-paste the main element instead of using @extend

We'll start by creating the orbit class.

.orbit {
  height: 6.25rem;
  width: 20rem;
  border-radius: 50%;
  border: 0.625rem solid #61dafb;
}
Enter fullscreen mode Exit fullscreen mode

This code is not used anywhere now.
But we can quickly add all these classes to our main div element like this.

.react {
  @extend .orbit;
}
Enter fullscreen mode Exit fullscreen mode

At this point, we have the primary orbit in place.

Main orbit ring

Before we add the other two orbit rings, let's first look at how we can add the dot in the center.
This will have to be a background on this main element.

But we don't want to fill the whole thing.
And we can leverage a radial gradient for this!

We saw a similar concept in the Dev.to logo where we had hard stops.
By using transparent stops, we can set the center color.

.react {
  @extend .orbit;
  background: radial-gradient(circle, #61dafb 15%, transparent 15%);
}
Enter fullscreen mode Exit fullscreen mode

As you can see, we start the gradient set to a circle at 15%, which will fill with the React blue.
And then, we transition to transparent from 15% onwards.

Atom + ring in CSS

And now, let's add the other two orbit rings.
We'll use the before and after pseudo elements.

.react {
  // Other classes
  position: relative;
  &:before,
  &:after {
    content: '';
    @extend .orbit;
    position: absolute;
    left: -0.625rem;
    top: -0.625rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

The main thing to note here, is that we extend the orbit again for the before and after.
Then we offset it by -0.625rem, which reflects the border width of the orbit.

And then, we can rotate each element a bit differently.

&:before {
  transform: rotate(60deg);
}
&:after {
  transform: rotate(120deg);
}
Enter fullscreen mode Exit fullscreen mode

By now, we have our react logo as intended.

Full React logo in CSS

The last thing we wanted to add was the animation. The original logo can rotate around the orb.

Let's add a rotate animation to the main element.

.react {
  animation: rotate 15s infinite linear;
}
Enter fullscreen mode Exit fullscreen mode

Some elements to note here:

  • rotate: This is the name of the animation we'll create in a second
  • 15s: How long each animation will take, 15 seconds in this case
  • infinite: how often the animation runs (forever)
  • linear: the type of animation, we want it to be equal over time, but you can also use ease-in.

The animation itself (named rotate) we can add like this:

@keyframes rotate {
  to {
    transform: rotate(1turn);
  }
}
Enter fullscreen mode Exit fullscreen mode

We say, animate to rotate exactly one turn (which equals 360 degrees).

And there you go, a one-div CSS React logo that animates.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Top comments (13)

Collapse
 
renanfranca profile image
Renan Franca

Hi @dailydevtips1!

You made it looks easy to do πŸ˜…πŸ€£!

I have already copy & past some SCSS into my projects, but I didn't fully understand the importance of it. After seeing this handy @extend in action, I am going to try to understand the SCSS codes.

Keep going!

Collapse
 
peerreynders profile image
peerreynders

This advice suggests that @extend can exhibit surprising behaviour as it will indiscriminately extend every instance of a matching selector that it finds.

In this particular case it doesn't matter as the class selector .orbit only appears onceβ€”so the compiled CSS looks like:

.orbit, .react:before, .react:after, .react {
  height: 6.25rem;
  width: 20rem;
  border-radius: 50%;
  border: 0.625rem solid #61DAFB;
}
Enter fullscreen mode Exit fullscreen mode

To control @extend better a placeholder selector can be bound to instead because placeholders only ever appear in one place:

%orbit {
  height: 6.25rem;
  width: 20rem;
  border-radius: 50%;
  border: 0.625rem solid #61DAFB;
}

.react {
  @extend %orbit;
  background: radial-gradient(circle, #61DAFB 15%, transparent 15%);
  position: relative;
  animation: rotate 15s infinite linear;
  &:before,
  &:after {
    content: "";
    @extend %orbit;
    position: absolute;
    left: -0.625rem;
    top: -0.625rem;
  }
  &:before {
    transform: rotate(60deg)
  }
  &:after {
    transform: rotate(120deg)
  }
}
Enter fullscreen mode Exit fullscreen mode

Now the compiled CSS looks like this:

.react:before, .react:after, .react {
  height: 6.25rem;
  width: 20rem;
  border-radius: 50%;
  border: 0.625rem solid #61DAFB;
}
Enter fullscreen mode Exit fullscreen mode

Notice how the placeholder selector is gone.

Alternately a @mixin could also be used:

@mixin orbit() {
  height: 6.25rem;
  width: 20rem;
  border-radius: 50%;
  border: 0.625rem solid #61DAFB;
}

.react {
  @include orbit();
  background: radial-gradient(circle, #61DAFB 15%, transparent 15%);
  position: relative;
  animation: rotate 15s infinite linear;
  &:before,
  &:after {
    content: "";
    @include orbit();
    position: absolute;
    left: -0.625rem;
    top: -0.625rem;
  }
  &:before {
    transform: rotate(60deg)
  }
  &:after {
    transform: rotate(120deg)
  }
}
Enter fullscreen mode Exit fullscreen mode

In the case of the @mixin, the declarations are copied to the @include sites instead.

Collapse
 
dailydevtips1 profile image
Chris Bongers

@peerreynders A wild shot here, but you wouldn't be interested in a job over at daily.dev?

Thread Thread
 
renanfranca profile image
Renan Franca

😱

Collapse
 
dailydevtips1 profile image
Chris Bongers

Oh nice, learned something new about that placeholder selector!
Thanks Peer πŸ™Œ

Collapse
 
renanfranca profile image
Renan Franca

Thank you for the detailed explanation πŸ˜ƒ

Collapse
 
dailydevtips1 profile image
Chris Bongers

Awesome keep it up Renan

Collapse
 
arndom profile image
Nabil Alamin

This a wonderful series

Collapse
 
dailydevtips1 profile image
Chris Bongers

Thanks Nabil

Collapse
 
shivams136 profile image
Shivam Sharma

You should create CSS logo series in dev.to and add posts in it so that your audience can get all at one place.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Ah good point I actually forgot to do that, thanks Shivam.

Collapse
 
svgatorapp profile image
SVGator

This is such a fun series!

Collapse
 
dailydevtips1 profile image
Chris Bongers

Thank you πŸ’–