so, to set the scene: When i decided that i wanted to make a little personal website for myself, i didnt know anything about webdev whatsoever. i barely ever touched html and css and i had no idea how to set up a webserver or how the structure for a website worked. so naturally i looked at random blog posts to try and understand whats going on. and thats how i got
one of the blog posts i came across (i have no idea if ill ever find that again) talked about the folder structure they use for their websites and it made a lot of sense to me. the idea looks like this:
you have folders for anything you need globally like css and js at the root and your pages seperately in a folder. this seemed very sensible to me, since you dont have your pages sitting at the root, mixing with the other folders you might have flying around.
normally this would mean that my homepage would be at crim.in/www instead of crim.in. for this reason the blog post had their nginx config set up in way where any request to the root url gets sent to the /www folder, with requests to the css and other folders being sent on their way normally:
server {
server_name crim.in;
location / {
root ./public/www;
}
location /images/ {
root ./public;
}
location /badges/ {
root ./public;
}
location /favicon.ico {
root ./public;
}
}
this has the nice side effect that anything outside the page structure has to be explicitely provided to users. i dont know if this is 100% safe, but things arent going to be immediately accessible if i dont want them to be.
however, this came with a problem. when i worked on my website locally
and wanted to load a stylesheet i had to awkwardly
link to it with a relative link like "../css/common.css",
because the absolute structure of my website would appear differently
depending on if it was accessed through nginx on my server or my local folder structure.
Apparently,
according to my girlfriend, structuring a website like this is super cursed.
apparently i should just have the root of my pages in the root
of my folder structure and the other folders either chaotically
in between my pages or in an assets folder.
so i did what i probably should have done from the start and set up a
this has a similar config to the one running on my server, so the site it hosts
behaves in the exact same way. you can run nginx as a user in the current
directory with your desired config file using nginx -c nginx.conf -p ..
using this, i wrote a little command for
lite-xl, my text editor of choice, that
allows me to start nginx and open the website without having to type out anything:
["custom:start nginx"] = function()
dir = core.project_dir
core.log(string.format("starting nginx in root directory %s", dir))
nginxProcess = process.start({"nginx", "-c", "nginx.conf", "-p", dir})
nginxProcess:wait(3000)
local returnCode = nginxProcess:returncode()
if returnCode ~= 0 then
core.log(nginxProcess:read_stderr())
core.log("nginx failed to launch")
return
end
core.log("nginx started successfully")
system.exec("xdg-open http://localhost:8000")
end,
and an even more little command to stop nginx again:
["custom:stop nginx"] = function()
local dir = core.project_dir
system.exec(string.format("nginx -c nginx.conf -p %s -s stop", dir))
end,
this setup has the super nice bonus effect of being able to access the website from other devices on my local network while im working on it, for example to check if the phone version works as it should.
when working on the styling for this post i needed some kind of syntax highlighting. i found microlight, which is very lightweight and looks pretty nice. im not entirely sure yet if im going to stick with it but i wanted to put it here because it is neat.
okay, lets Actually talk about the site itself. i use mostly html and css and very little javascript, just where it makes my life easier.
when writing html, one of the issues that come up is that you kind of end up
having millions of divs that all look the same in your dom tree with classes to style them.
instead i really like using
autonomous custom elements.
you can just make up a name for an element, as long as it contains a hyphen.
it will extend HTMLElement by default and no javascript is needed to use it, but js can be used to change its
behavior and make it extend other element clases.
what this means in practice is that instead of creating a table of contents like
<div class="contents">...</div>
you can make it more readable by creating a custom element like
<article-contents>...</article-contents>,
making it a lot more obvious what an element does, without the clutter of a class.
in the same vein i like to use
custom attributes
for additional styling.
so for a thin version of that table of contents instead of
<div class="contents thin">...</div>
i do
<article-contents thin>...</article-contents>.
this is what the css would look like for the div version:
div.contents {
//styling here
&.thin {
//thin version styling here
}
}
and for the custom element version that i prefer:
article-contents {
//styling here
&[thin] {
//thin version styling here
}
}
i also use custom attributes to style non-custom elements, even though youre not really supposed to as per the spec. here are some examples:
<h3>this is a title<span subtitle>and this is a subtitle</span><h3>
im a silly little link
<a decorated href="/images/hehe.jpg">im a silly little link</a>
i have some custom elements that have most of their html defined in a javascript file. these are elements like my header and footer that are relatively complicated while not having any changing content. so instead of having them clutter every html file i just let js fill in their innerHTML.
class Header extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<style>
//all header styling here, notably also
@media (width <= 1024px) or (hover: none) {
wide-header { display: none; }
slim-header { display: block; }
}
</style>
<wide-header>
...
</wide-header>
<slim-header>
...
</slim-header>
`;
}
}
document.addEventListener("DOMContentLoaded", (event) => {
customElements.define('main-header', Header);
...
}
if someone visits my website and has javascript disabled it will still work just fine, a few elements will just not be visible. for navigation i have a simple fallback header on my home page.
pawllie is the little talking cat on my home page. i used to have her implemented as a custom element with all the html and styling in javascript for clutter reasons, but i decided that that was pretty silly. after all, the entire goal in making pawllie was to see how much i can do with just html and css.
and it turns out, A Lot! pawllie if fully animated, reacts to you petting different areas, has speech bubbles you can click through and will even lie down after a while. this is an excerpt of her html:
<resizer-container>
<cat-container>
<speech-bubbles>
<speech-bubble id="b6">
...
</speech-bubble>
</speech-bubbles>
<cat-svg class="sitting pettingInteraction">
<svg viewBox="0 0 100 100">
<path id="cloud-bg" d="M10,105 L10,90 ..." />
<path id="tail" d="M75,100 L80,100 ..." />
<path id="body" d="M30,35 L25,50 ..." />
<path headpart id="head" d="M30,35 L50,35 ..." />
<path headpart id="headStroke" d="M30,35 L50,35 ..." />
<path headpart id="rightEar" d="M54,15 L50,0 L45,12" />
...
<path id="leftPaw" d="M25,50 L31,94 ..." />
<path id="rightPaw" d="M45,70 L44,94 ..." />
<polyline id="headTrigger" points="30,35 50,35 ..." />
<path id="cloud-fg" d="M2,96 L-5,105 ..." />
</svg>
</cat-svg>
<cat-svg class="lyingDown-transition">
...
</cat-svg>
<cat-svg class="pettingInteraction lyingDown">
...
</cat-svg>
</cat-container>
</resizer-container>
yes, this uses a mix of classes and attributes for styling, would it surprise you that making this cat took a while?
there are obviously easier ways to do this, but i hand typed All the svgs directly in the html file. and i also hand typed All the svg animations in the css.
this is probably something you should never do because it is Really messy and stupid.
i also dont think i want to explain all the weird desicions i made unles you really want me to,
but feel free to check the source
of my home page and the css if youre interested.
i guess one kind of useful thing i can talk about is the
if you see something on my website that you want explained, send me an email to
q@crim.in and i might add it to this page.
id be happy to hear any feedback you have, really. i might put a kind of comments section here,
similar to my hi page.