Actions

Work Header

Rating:
Archive Warning:
Fandoms:
Additional Tags:
Language:
English
Stats:
Published:
2026-05-14
Completed:
2026-08-08
Words:
1,912
Chapters:
2/2
Comments:
50
Kudos:
48
Bookmarks:
17
Hits:
599

Moving Starry Sky Background

Summary:

A moving starry sky background, done with css and html!

Notes:

Edit 8/8/2026: Updated a chapter for falling stars. Due to the way the stars clip in and out of the borders, it's recommended to read this chapter by chapter rather than as a full work.

I had so many plans to write, and then I got hit with sickness right after I posted my last fic. Unfortunately despite my brain not being able to turn ideas to coherent words, my fingers were still itching to write, so I decided to write up this guide on how I did the moving starry sky background for said last fic instead. It’s definitely a bit janky, but I think it looks pretty cool, so I figured maybe some other people would get some use out of it?

Here's my last fic that uses this in a more gradient style, where the stars gradually go from less dense to more dense (Note the tags and warnings of the fic, you can just scroll to see the effects though). Also, highlighting is a bit janky with the skin on, so you may want to turn off creator’s style if you’re clicking links and/or copypasting any code from here.

Edit 5/14/2026: Highlighting is fixed, courtesy of Charles_Rockafellor!

(See the end of the work for other works inspired by this one.)

Chapter 1: Rotating Stars

Chapter Text

Starry Sky

This was inspired by Green Rain font, from The Matrix by Charles_Rockefellor, specifically this section on floating motes. (Thank you for leaving the buggy code up <3). Just that instead of the matrix glyphs, I used various black and white icons that could reasonably work for a starry sky. Then it all gets put into the :after of a class, and the divs are sporadically inserted throughout the work.

Ideally, you would have a few different variations of background skies. I did end up writing a Python script to automatically generate them for myself, just because I didn’t want to do it by hand. If you want to run it yourself, I put the code I used below (I just commented out the different elif statements depending on the star density I wanted). But otherwise, I decided to just put up a site with a bunch of different patterns. Just copy as many random segments of it as you want and boom, background!

import random

small_stars_dots = ['﹆', '﹅', '𓈒', '⭒', '˖', '⋆', '˚', '₊', '・', '°', '˳', '˙', '.', '*', '˖', '꙳', '⸝', '◞', '⬪', '⬩', '༶']
small_stars_designs = ['࿔', '༄', '*', '⁺','◌', '⬨']
large_stars = ['⊹', '✶', '★', '✧', '✦', '✰', '☆', '+', '✮', '❅', '✯', '⁂', '✫', '✭', '✬', '✵', '◈', '✲']
large_swirls = ['๑', '໑', '७', '୭', '១']

pattern = ""

for j in range(0,500):

  rand = random.randrange(1, 5000)

# 2% stars
  if (rand <= 4900):
    pattern = pattern + "  "
  elif (rand > 4900 and rand <= 4950):
    pattern = pattern + random.choice(small_stars_dots) + "          "
  elif (rand > 4950 and rand <= 4975):
    pattern = pattern + random.choice(small_stars_designs) + "          "
  elif (rand > 4975 and rand <= 4990):
    pattern = pattern + random.choice(large_stars) + "            "
  else:
    pattern = pattern + random.choice(large_swirls) + "            "

# 5% stars
  if (rand <= 4750):
    pattern = pattern + "  "
  elif (rand > 4750 and rand <= 4900):
    pattern = pattern + random.choice(small_stars_dots) + "          "
  elif (rand > 4900 and rand <= 4950):
    pattern = pattern + random.choice(small_stars_designs) + "          "
  elif (rand > 4950 and rand <= 4990):
    pattern = pattern + random.choice(large_stars) + "            "
  else:
    pattern = pattern + random.choice(large_swirls) + "          "

# 10% stars
  if (rand <= 4500):
    pattern = pattern + "  "
  elif (rand > 4500 and rand <= 4650):
    pattern = pattern + random.choice(small_stars_dots) + "          "
  elif (rand > 4650 and rand <= 4700):
    pattern = pattern + random.choice(small_stars_designs) + "          "
  elif (rand > 4700 and rand <= 4900):
    pattern = pattern + random.choice(large_stars) + "            "
  else:
    pattern = pattern + random.choice(large_swirls) + "            "

# 15% stars
  if (rand <= 4250):
    pattern = pattern + "  "
  elif (rand > 4250 and rand <= 4500):
    pattern = pattern + random.choice(small_stars_dots) + "          "
  elif (rand > 4500 and rand <= 4750):
    pattern = pattern + random.choice(small_stars_designs) + "          "
  elif (rand > 4750 and rand <= 4950):
    pattern = pattern + random.choice(large_stars) + "            "
  else:
    pattern = pattern + random.choice(large_swirls) + "            "

# 20% stars
  if (rand <= 4000):
    pattern = pattern + "  "
  elif (rand > 4000 and rand <= 4300):
    pattern = pattern + random.choice(small_stars_dots) + "          "
  elif (rand > 4300 and rand <= 4500):
    pattern = pattern + random.choice(small_stars_designs) + "          "
  elif (rand > 4500 and rand <= 4800):
    pattern = pattern + random.choice(large_stars) + "            "
  else:
    pattern = pattern + random.choice(large_swirls) + "            "

with open("output.txt", "w", encoding="utf-8") as f:
  f.write(pattern)

Then, for the css:


#workskin .overlap {
  position: relative;
}

#workskin .overlapBackground {
  position: absolute;
  opacity: 50%; /* this can also be adjusted if you want your stars more/less transparent */
  overflow: auto;
  -webkit-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  -moz-user-select: none;
  user-select: none;
  transform: rotate(0); /* this line and the one after are for animation purposes, we’ll get to that in the next section */
  transition: transform 900s;
}

#workskin .border {
  border: 0px;
  width: 99%;
  height: 100%;
  display: inline;
}

#workskin .stars:after { /* you can repeat this as many times as you want for each star pattern, just make sure you name them all differently (I just numbered them stars1, stars2, etc) */
  content: "PUT YOUR STARRY BACKGROUND HERE";
  z-index: -5 !important;
}

#workskin .yellow { /* this is if you want to color your stars something specific */
  color: rgba(207, 162, 12);
}

Then, in the HTML, use <div class="border"><div class="overlap"><div class="overlapBackground"> <span class="yellow stars"></span></div></div></div> to put the stars in. You’ll have to do this multiple times throughout the work, since the animations will spin the stars from the center of the element, and if it’s all in one div (unless you have a really short work) you’ll just have moments of giant empty gaps.

Note: If you only want a static unmoving background, you can do all of it in one div, since the effect of the animations doesn’t matter.

I write on google docs, and I find that one div per page is just about good enough. For a more visual example, using each colored box to represent a different star pattern, you want something like this:

That way, when things rotate, we have something like this:

And the overlap from the stars creates a pretty cool swirling effect.

Note 8/19/2026: I would also highly recommend only adding the stars once you no longer need to be using the Rich Text editor (if you use it in the first place). And once you put the stars in in the HTML, do NOT switch back to the Rich Text editor. Ao3 tends to try to "fix" things when you convert back and forth between Rich Text and HTML, which usually works fine for normal stuff, but starts breaking down once you try anything fancy.

Animation

This is pretty much straight from Auto Run Transitions by feindcode. As mentioned in the first part, the last two lines of overlapBackground contain the transition and transform elements:

#workskin .overlapBackground {
  position: absolute;
  opacity: 50%; /* this can also be adjusted if you want your stars more/less transparent */
  overflow: auto;
  -webkit-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  -moz-user-select: none;
  user-select: none;
  transform: rotate(0); /* these two lines over here */
  transition: transform 900s;
}

 

And then we add this to actually get it to rotate live:


#workskin:is(body.javascript *) .overlapBackground {
  transform: rotate(3600deg);
}

This will rotate your elements 3600 degrees (10 full loops) in 900 seconds (15 mins). The time (in seconds) after the transform is basically how long the background will rotate for, so you’d want to adjust that based on how long you think it would take someone to read your fic. Then, to control the speed of the rotation, you would increase the number of degrees in the rotation. Basically, the lower the time and the higher the degree, the faster the spin, and the higher the time and the lower the degree, the slower the spin.

(This also has the effect of making the left-right scroll bar go a bit crazy at the bottom, but I wasn’t able to figure out a way to fix that—maybe someone else knows?)

(Edit 7/2/2026: A fix has been found by Lucentt! Adding overflow-x: clip; to the .overlap class of the CSS will get rid of the left-right scroll bar. The full code will have the edit!)

 

Full Code

And here’s all the code for the starry background in this fic!


#workskin .overlap {
  position: relative;
  overflow-x: clip;
}

#workskin .overlapBackground {
  position: absolute;
  opacity: 50%;
  overflow: auto;
  -webkit-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  -moz-user-select: none;
  user-select: none;
  transform: rotate(0);
  transition: transform 900s;
}

#workskin .border {
  border: 0px;
  width: 99%;
  height: 100%;
  display: inline;
}

#workskin .stars1:after {
  content: "          ១            ﹆                              ໑                                                    .                          ១                          ✲              *            ⭒                            ✲                                      ୭              ໑                ✭                ✧                  ★                      ˙                  ✦                ˳          ⁺                    ★                      ୭            ✦            ⭒            ༶            °                ◌              ✵            ⬨              ໑                                      ˖                  ˖          ✭            ・                  ༄              +                              *            ˖                        *              ໑                ❅            ✯                  ୭              ✫                  ७            ⊹                ⁂                    ๑                ༄                ໑                                ๑              .                            ✰                  ⬨              ◈            ✲                ★              ✰                              ୭                    ୭                          ୭            ໑                    *                              ࿔          ✦            ७                          ១                                                      ☆                            ༄                                      ✲                                          ⸝                      ༄                          ໑                      ﹆          ◌          ꙳                  ﹅                                        ◈                ⬨                    ७                ⁂            ⬨                                *                      ⊹                ✧                                                            ˙                          ﹅              ࿔                                        ✲                          °            ✦                  ✫                                                          ༄                  ❅                        ✫                    ✬                                  .                      ១                ✧                ७                  ୭            ◌                +            ◞                          ⬨          ⁂                  ⁺              *            ◈              ១                                    ☆                                    ๑                  ◌          ⁺            ✲                                                ༄                    ✵                    ˖          ࿔                ७                ✲            °            ✰                              ࿔                ❅                          ・          ☆                    ˚                ✯              ७                      ⋆          *                            ⬩                +                  ୭                    °                ﹅          ﹆                      °            ★                                                                            *              ✶                        ˳                  ༄            ๑                ໑            ⬪            +                      ୭              ✰              ໑                                    ◌              ✫            ୭                ☆                        ࿔          ⬪                    *                ༶            ˚                +                    ✲                  ๑                  ១                      *                  ✶                                ⁺                            +              ༶                ⁺              ១              ✭                        ✦                      ࿔                    ༄                ១                              *                  ⸝            ✰              ⁺              ୭                                ⬩                ✲                  ★                    ༶          ✶                ✦                          𓈒            ₊              ˚                          ◌            ✮                                                ˖                  ୭                      ✰                ⬩              ७                          ✵                    ☆                              ✶                                  ⭒            ✯              ❅              ˖              ◞          ७            ७                              .              ✫                                  ✰                          ˖                                    ✦  ";
  z-index: -5 !important;
}

#workskin .stars2:after {
  content: "[These are just more star patterns, for the sake of not cluttering up the entire screen I've omitted the other ones]";
  z-index: -5 !important;
}

#workskin .stars3:after {
  content: "[I really like stars :D]";
  z-index: -5 !important;
}

#workskin .stars4:after {
  content: "[Isn't space so beautiful?]";
  z-index: -5 !important;
}

#workskin .stars5:after {
  content: "[Wheeeeeeee]";
  z-index: -5 !important;
}

#workskin .stars6:after {
  content: "[Hope you have fun with this ^^]";
  z-index: -5 !important;
}

#workskin .yellow {
  color: #C28500;
}

#workskin:is(body.javascript *) .overlapBackground {
  transform: rotate(3600deg);
}