DEV Community

Cover image for Let's Build a Night Sky using Pure SCSS!
Sobhan Dash
Sobhan Dash

Posted on

Let's Build a Night Sky using Pure SCSS!

I was working on a new version of my portfolio and thought, let's go a little on the learning side. So I researched a bit and decided to use scss.

I decided to create a night sky effect. So here it is!

HTML Code

<div class="main-container">
      <div class="sub-container">
        <div class="sky">
          <div class="stars"></div>
          <div class="stars2"></div>
          <div class="stars3"></div>
          <div class="comet"></div>
        </div>
      </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Nothing special here, just a few divs for different sizes of stars and a comet.

Let's move on to the good stuff!

Constant variables(SCSS)

Before moving on to the various properties, a few constants need to be defined.

$starFieldWidth: 2560;
$starFieldHeight: 2560;
$starStartOffset: 600px;

$starOneScrollDuration: 100s;
$starTwoScrollDuration: 125s;
$starThreeScrollDuration: 175s;
$numStarOneStars: 1700;
$numStarTwoStars: 700;
$numStarThreeStars: 200;
$numComet: 10;

html {
  height: 100%;
  body {
    width: 100%;
    height: 100%;
    margin: 0;
  }
}
Enter fullscreen mode Exit fullscreen mode

Much of it is self-explanatory. We have 3 types of stars which will have slightly different sizes. They have their transition durations as well. The width and height spread out the stars a bit, it is of course personal preference so go wild.

Main Container

.main-container {
  display: block;
  position: relative;
  width: 1200px;
  height: 600px;
  background: linear-gradient(to bottom, #201c2f 0%, #100751 100%);
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
Enter fullscreen mode Exit fullscreen mode

You can change the width and height to your preference, the rest are just to center it to the middle and give a galactic feel to the background.

Function to create the stars

@function create-stars($n) {
  $stars: "#{random($starFieldWidth)}px #{random($starFieldHeight)}px #FFF";

  @for $i from 2 through $n {
    $stars: "#{$stars} , #{random($starFieldWidth)}px #{random($starFieldHeight)}px #FFF";
  }
  @return unquote($stars);
}
Enter fullscreen mode Exit fullscreen mode

We are creating a function to generate stars at random positions in the sky. The function will be used as a shadow. So let's see how!

Animations

@keyframes animStar {
  from {
    transform: translateY(0px);
  }
  to {
    transform: translateY(-#{$starFieldHeight}px)
      translateX(-#{$starFieldWidth}px);
  }
}

@keyframes animShootingStar {
  from {
    transform: translateY(0px) translateX(0px) rotate(-45deg);
    opacity: 1;
    height: 5px;
  }
  to {
    transform: translateY(-#{$starFieldHeight}px)
      translateX(-#{$starFieldWidth}px) rotate(-45deg);
    opacity: 1;
    height: 800px;
  }
}
Enter fullscreen mode Exit fullscreen mode

As you can see, we are moving from the bottom right to the top left of the container in the animations. And with the random stars getting generated, we get a lively feel to the sky.

Star Templates!

@mixin star-template($numStars, $starSize, $scrollSpeed) {
  z-index: 10;
  width: $starSize;
  height: $starSize;
  border-radius: 50%;
  background: transparent;
  box-shadow: create-stars($numStars);
  animation: animStar $scrollSpeed linear infinite;
  &:after {
    content: " ";
    top: -$starStartOffset;
    width: $starSize;
    height: $starSize;
    border-radius: 50%;
    position: absolute;
    background: transparent;
    box-shadow: create-stars($numStars);
  }
}

@mixin shooting-star-template($numStars, $starSize, $speed) {
  z-index: 10;
  width: $starSize;
  height: $starSize + 80px;
  border-top-left-radius: 50%;
  border-top-right-radius: 50%;
  position: absolute;
  bottom: 0;
  right: 0;
  background: linear-gradient(
    to top,
    rgba(255, 255, 255, 0),
    rgba(255, 255, 255, 1)
  );
  animation: animShootingStar $speed linear infinite;
}
Enter fullscreen mode Exit fullscreen mode

For those who are not familiar with scss, mixins allow us to define styles that can be re-used throughout your stylesheet.
It is kind of like a component/function which can be called multiple times.

Here the star template is generating the stars using the above function.

Will the above code work?

Not really. Unless we use the mixins, we don't see any results, so to get them we need to use @include.

.stars {
  @include star-template($numStarOneStars, 1px, $starOneScrollDuration);
}
.stars2 {
  @include star-template($numStarTwoStars, 2px, $starTwoScrollDuration);
}
.stars3 {
  @include star-template($numStarThreeStars, 3px, $starThreeScrollDuration);
}
.comet {
  @include shooting-star-template($numComet, 5px, 10s);
}
Enter fullscreen mode Exit fullscreen mode

Working Pen

And that's the end! Pretty simple right? Use it in your next project, and let me know how it worked for you.

Top comments (1)

Collapse
 
svgatorapp profile image
SVGator

Wicked!