made a really cool effect in css you'll see it in 255 days
In july 2024 I made this really cool effect that I thought from Serial Experiments Lain. I thought it would be a good idea to put it in an april fools joke since it's no use for normal sites, since it requires a span in every letter to work, meaning it makes unpenetrable html code, and it has some weirdness like all words fusing together when text-indent is set and it glitch-de-hovering the link when you hover over it not in the middle.
First, I thought about the cool effect in Lain's navi and thought about making it in CSS. So I went searching but there was nothing, I would have to come with my own CSS. It took a while to know what to do. I found the rotate function, and already knew a little about transitions, so I went to work with it, but it didn't work. Some time later I found that it doesn't work with inlines, only inline-blocks or blocks. I don't remember what I did that made titles work, I didn't have any code to mitigate the inline -> inline-block transition in the website's txt saved, only the rotate code.
So I applied the CSS and the text was rotating, but the letters were not rotating to the other direction. I wanted the letters to rotate counter to create the cool effect, so I thought how about I just add CSS to make the letter rotate counter, and it worked, but it required me to put every letter inside a span class, which would be impossible to do for the entire site. So I thought of only making the effect on the nav.
But fast-forward later, in Februray, I decided to make a script in Python to prepare all <a>
s. The nav titles I could do manually. It took me about 2 hours to make a test that transforms a test text, because there was a bug that I couldn't find the cause, turns out it was an error I made on the outer loop (I was only looking at the inner loop before that). Half an hour later I had the file read mechanism done. I thought on just printing the transformed text to the terminal and copying it, instead of going into writing files which would be a little bit harder, but later I thought better and ended up just coding it which was pretty easy, and it then allowed me to automate the entire process with bash. I also did a mechanism to transform spaces in
so it shows spaces correctly, which was kind of a hack, and a simple argparse for the filename. I didn't do automatic file getting, as I could do that manually or with bash much easier.
I tested on the spot, and there were some weirdness like text-indent (from lists) making the text fuse up in a single spot.
3 days before april first it was time. I setup a clone folder of my site and ran the script in all the pages. Added the CSS, had to comment out the indent-second-line class so the text doesn't fuse up in lists, and added a rule to decorate all of it with underlines.
A day later I decided I was lazy to manually do all h1's so I coded it into the script. I had a bug where it would create clones of the entire page on a single file, but quickly got that taken care of. Some !important here and margin there, h1's were all working. I ran the script again with the bash oneliner for i in *.html; do ./main.py "$i" --h1; done
and it was done!
You can view an april first snapshot of my website in the Wayback Machine.
The script
Here's the script if you want to try it out:
#!/usr/bin/python
import argparse
import os
parser = argparse.ArgumentParser()
parser.add_argument("file")
parser.add_argument("--h1", action="store_true")
args = parser.parse_args()
try:
os.mkdir("out")
except FileExistsError:
print("Directory 'out/' already exists, undefined behaviour may or may not occur")
if args.h1:
try:
os.mkdir("outh1")
except FileExistsError:
print("Directory 'outh1' already exists, undefined behaviour may or may not occur")
def add_class(lines, tag, h1):
for line in lines:
line_find_index = line.find(tag)
while line.find(tag, line_find_index) != -1:
i = 0
nbsp = 0
while line[line_find_index - i - 1] != ">":
if nbsp:
line = line[ : line_find_index - i - 1] + "<span class=\"rl\">"+ line[line_find_index - i - 1 : line_find_index - i + 5 ] + "</span>" + line[line_find_index - i + 5: ]
nbsp = 0
else:
line = line[ : line_find_index - i - 1] + "<span class=\"rl\">"+ line[line_find_index - i - 1] + "</span>" + line[line_find_index - i: ]
if line[line_find_index - i - 2] == " ":
line = line[ : line_find_index - i - 2] + " " + line[line_find_index - i - 1: ]
nbsp = 1
i += 1
i = 0
line_find_index = line.find(tag, line_find_index + 1)
if h1 != 1:
with open("out/" + args.file, "a") as out_file:
out_file.write(line)
else:
with open("outh1/" + args.file, "a") as out_file:
out_file.write(line)
with open(args.file) as src_file:
lines = src_file.readlines()
add_class(lines, "</a>", 0)
if args.h1:
with open(f"out/{args.file}") as src_file:
lines = src_file.readlines()
add_class(lines, "</h1>", 1)