style.css, ./style.css, /style.css, ../style.css?!

Only a year ago or so i finally definitively learned the difference between these, and life became so much better! Hopefully this tutorial will help you get more efficient with your site structure, too, since these techniques make it so much easier to manage referencing common resources.

Definitions

  • Resource - some file we want to refer to inside an .html page, like a .css storing some styling, a .js with some code, a .png image, etc.
  • Website root, webroot, root - the base directory your site resides in. For neocitizens - the first folder you see when you press "edit site". The "main" folder that has no parent folder in your site structure. To the outside world, accessing the root folder equals accessing your site by its name, e.g. https://auberylis.moe or https://astrossoundhell.neocities.org for my site. That's why index.html from the root folder is the one that gets loaded when someone visits your site!
  • Absolute path - a full path that points to some resource from the root folder. In case of websites, that would be the website root. The absolute path should tell where the file is all the way from the root directory, through all the subfolders, to the file.
  • Relative path - a partial path that points to some resource relatively to the resource that refers to it. For example, if two resources are in the same folder, one can refer to the other relatively to itself, omitting the rest of the would-be-full path.

Resource Files

When we make HTML pages, we often end up adding styling and interactivity to it with css and js respectively. It is possible to write those right in the HTML file using <style> and <script> tags respectively. This is handy, but makes your life hell the moment you want the same style or code on two separate pages. What if you have 100 pages, and it's Halloween, and you want to add seasonal styling or a spooky popup? Editing all 100 pages separately it is!

That is why we make separate resource files with style and code, and then hook them up to the html page. For CSS, we connect a .css file using <link rel="stylesheet" type="text/css" href="path-here...">. For JS, instead of writing code inside the <script> tag, we leave it empty, and instead refer the resource using the src attribute, like <script type="text/javascript" src="path-here..."></script>. This allows us to use the same resource on many pages, so when you want a style or behaviour change, you can simply change one file, and it will propagate over to everything that refers to it.

This much is clear to most webmxters. What raises questions and leads to bugs is the path-here... part: how exactly you denote your path means the world to the machine!

Example Structure

Imagine the following site structure. In the website root is the main landing html file index.html, some styling separated into style.css, some interactivity javascript in code.js, a tiling background image background.png and a blog folder. The blog folder contains the blog index blog/index.html with an entry link list, some blog-specific css in blogStyle.css, and another subfolder called entries for the actual blog posts. The blog/entries folder has two entries as separate html files for year 2023 and 2024: blog/entries/2023.html and blog/entries/2024.html

+ site.neocities.org // website root ~ style.css ~ code.js ~ index.html ~ background.png + blog // folder ~ index.html ~ blogStyle.css + entries // subfolder ~ 2023.html ~ 2024.html

To demonstrate various location methods, let's set some goals. We want all the HTML pages to refer to style.css that's at the root folder. All the HTML pages in blog (including the ones in blog/entries/) should also use the blog-specific styling from blog/blogStyle.css. Each page that's not the landing index.html should have a link to the said website root landing index page. The blog entry HTML pages should also point to the blog index blog/index.html. We want every page to use the same patterning image background.png for its background.

Relative Location

Let's start with the site's landing page, index.html stored at the website root. It has to use style.css and code.js. Both files are stored in the same folder right next to the HTML page itself. In such case, the easiest way to address a resource is by using a relative path. A relative path may be presented in two ways: either starting with a ./, or just with the file/subfolder name from the same folder the referrer is in. The path will be interpreted as implicitly having the referrer's location before the provided path string. Hence, the task of referring to style.css and code.js from index.html can be solved equally well inside the <head> tag in two ways:

and

The . at the start of the path is an explicit reference to the path itself. In fact, on most operating systems, every folder has two hidden files called . and .. that are referrences to itsef and its parent folder respectively! So, ./[filename] means "in where we are now, find [filename]". Personally, i prefer denoting this dot-slash explicitly instead of just starting with the subfolder name, so that it's obvious what's going on, but simply omitting any dots and slashes should have the same effect.

This also means that for linking from the site home index.html to the blog index blog/index.html, both <a href="blog/"> and <a href="./blog/"> will work; no need to explicitly type "index.html", since most servers serve index.html by default if the filename is not provided. To refer to one of the blog entries, both <a href="blog/entries/2023.html"> and <a href="./blog/entries/2023.html"> will suffice.

Importing blog/blogStyle.css to all the blog-related pages is a similar task. For blog/index.html we can do

Since blog/blogStyle.css and blog/index.html are in the same folder blog, referring the CSS file from HTML is trivial by using the relative path notation. Again, i prefer an explicit dot-slash, but this also would've worked by simply doing href="blogStyle.css". For the entry pages like blog/entries/2023.html, pointing to the same style will look like this:

Since the actual CSS file is one file layer up, in the parent folder of where the HTML file is, we can point to it using ../ - roughly translated to "in this folder's parent folder, find". So, from blog/entries/, we navigate to blog/, in which we find blogStyle.css. Fun fact: blog/blogStyle.css and blog/entries/../blogStyle.css are the same path, since we're allowed to go down and up in the file/folder hierarchy in any order and as many times as needed in a single path string.

Absolute Location

Now that the landing index.html is figured out, the other three HTML pages have to refer to style.css stored at the website root as well. They are not in the same folder with the style file, which means just copypasting the link and script tags from index.html won't work. However, this doesn't mean we can't use relative location at all; remember how .. means "the parent folder"? Nothing stops us from putting

to blog/index.html's <head>. What this href means is "go to the parent folder and search for style.css". For a blog entry, like blog/entries/2023.html, we can do

- no one prohibits us to stack ../s to express "go to the parent folder, in it search for its parent folder, in it search for style.css". This is all good and functional, but what if the structure is much more complex? I can assure you, it is very painful to count ../s, and even more painful to debug mistakes that are caused by mis-counting ../s!

Let's try a different approach that makes life easier: absolute location. It's very easy to refer to the root directory by starting your path with a / - just a slash, no dot! Remember, the dot means "current directory", which we don't want in absolute location. Instead, we want the root directory, which is denoted with a single slash. In your computer, going to the "/" directory ("\" for windows users) will take you to the root folder of the operating system! But when used on a website, it refers to the website root. So on my site, /favicon.ico is treated by the browser as https://auberylis.moe/favicon.ico. In this article's example, putting href="/style.css" to the <link> tag will work for both /blog/index.html and /blog/entries/2023.html - so much clearer, and one less thought to think, like so:

Likewise, it's now easy to fulfil the task of linking to the site root's index.html from all other pages - no matter how deep in subfolders it may be buried, it's as simple as

To Website Index

Remember, no need to denote "index.html" because if no filename is there, it will be fetched automatically. What this href essentially means is "go to the website root and give me [no filename provided] from it", which the server knows to interprete as "go to the website root and give me index.html".

Which is Better?

We also wanted a link to the blog index on every blog entry page. This task can be optimally done using a relative path as <a href="../"> - since the entries are stored in blog/entries/, and the blog index is at /blog/index.html, it is enough to just point at the parent directory of blog/, and index.html will be automatically fetched, since no filename is provided after the last /. However, the same exact effect can be done with an absolute path notation as <a href="/blog/"> - website root to blog folder, and again - no filename provided, so index.html is assumed to be the request. Which is better?

The answer is boring and expected: neither is exactly better. By location time, the difference is zero to the end user. By notation length, both are pretty short; one's a bit shorter, the other's a bit more explicit. One may want to take into account the way they organize and change the website. If you feel like your blog, with all of its entries, may as well move from blog/ to a new folder thoughts/, and you used absolute links, then you're in for manually replacing every href="/blog/" with href="/thoughts/, whereas a relative href="../" will work the same regardless of the parent folder's name. On the other hand, if at some point, you would want to group your entries into folders by year, say, blog/entries/2023/july.html, any link at the blog entry page with href="../" will now point to the year folder, blog/entries/2023 in this example. And now each href="../" must become href="../../" - or an absolute href="/blog/. So, it is up to you to decide which way to go, taking into account the further actions you may take with your site's file structure.

Paths in CSS

The final task to cross out is having the same background image in each page - refer back to the example file structure if you're lost. To recap: we have an image called background.png and a stylesheet called style.css in the website's root, and we want all HTML pages to use them, regardless of their location on the website. We already referred to the stylesheet from all pages using absolute location by starting the stylesheet path string with an /. However, what of the image? In the CSS file, using it would look something like

body { background-image: url("./background.png"); }

Note how the path is relative - it starts with a ./ which means "in the current folder, find". So, naturally, it will work on index.html, since background.png is right next to it in the same folder. But, at first surprisingly, it will also work on every other page, too!

It may be counterintuitive at first, but the trick lies in the CSS file itself. Sure, the path is relative - but to what? When you type out some path in your HTML markup, it is relative to the HTML file's location. But when you type it out in a CSS stylesheet, it's relative to the stylesheet itself - not to the file that refers to the stylesheet! Since in our case the stylesheet is next to the image, this relative path works flawlessly, no matter where the HTML page using the stylesheet is located. In hindsight, this design decision makes a lot of sense precisely because CSS is intended to be reused across many pages. The pages may be all over the website, and if the images and other files referred to using url("[filename]") were relative to the HTML page and not to the CSS sheet, many pages would require a copy of the stylesheet, updated according to its location. The fact that inside a CSS file, paths are relative to that CSS file eliminates such need.

Of course, absolute path notation is still valid and works the same way in CSS as explained earlier in HTML; it's possible for different CSS sheets to access the same resource somewhere else without going through the ../ hell by simply locating absolutely and starting the path with a /. On my site, i made a folder called common at the website root, and put all the resources that repeat across pages to it, like font files, backgrounds, even js and css files. It's very easy then to access those files by using an absolute location starting with /common/[theRestOfPath] - which translates to "at the website root, go to common, in which find [theRestOfPath]"

Conclusion

Now you know the difference between ./style.css and /style.css, and also style.css and ../style.css! Or maybe you already knew it, but had your knowledge reinforced. Either way, it's important to remember and keep an eye on the difference between relative and absolute paths when programming for web. Not only will paying attention to that little (dot-)slash save you precious debugging time, but also it will help you make your website much faster by reusing common resources, which the browser won't have to reload each time, dragging them out of its cache instead. PLURR!

← Back to the web tutorial index