Let's Build a Night Sky using Pure SCSS!
Tags: css, webdev, tutorial, todayilearned
Published: 2022-03-23 09:31:43

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

```html
<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>
```

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.

```scss
$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;
  }
}
```
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
```scss
.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%);
}
```
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
```scss
@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);
}
```
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
```scss
@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;
  }
}
```
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!
```scss
@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;
}
```
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`.
 
```scss
.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);
}
```
### Working Pen

{% codepen https://codepen.io/sobhandash/pen/ExmOPEz %}

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