make your own personal website with html and neocities, for free

2022-01-10

word count: 2852

approx reading time: 15 mins

intro

in this post i'll show how to setup a linktree-like personal webpage on neocities, explaining all of the html and css needed for it

you don't need any webdev experience or knowledge for this post, all the basic concepts will be explained!

setup neocities

the first step is to create an account on neocities:

neocities signup screenshot

it'll ask if you want to pay or not. you can check out what a paid account offers, but a free one will work just fine for what we need

after confirming your account and logging in, you'll see the following page:

let's get started screenshot

note: neocities has a cute html tutorial that you can go through if you have any other doubts after finishing this post.

click on Go to the dashboard >> to open your neocities dashboard:

dashboard screenshot

here you can see the list of files currently on your website. the most important one is index.html, which your website's home page

at this point, your website is already up and running! you can visit username.neocities.org (with your username instead of username), where you'll see something like:

empty neocities page

if we go back to the dashboard, and click on index.html, the following html editor will open up:

html editor

here we'll be able to edit the content on the page

intro to html

html consists of elements defined by tags, which are the things inside the funny < and > characters. for example, we have <html> on line 2. that's what we call an opening tag, which starts an html element. on line 32 we can find it's corresponding closing tag, which looks like </html>. it looks similar to the opening tag, but it has a sneaky / after the <. everything between an opening and a closing tag are what we call the element's children.

in html, most elements must have a closing tag, but there are some exceptions.

on line 13 you'll see <h1>Welcome to my Website!</h1>. change that line to <h1>im "your name here"!</h1> and hit the big save button at the top right corner. if you refresh the page at username.neocities.org, you'll see how the text has changed:

im annie h1 screenshot

im annie website screenshot

html has a bunch of different elements, each with a different meaning. the one we just edited is an <h1>, which is a heading (title). there's a few heading elements, from h1 to h6, for subtitles and subsections.

another common element is <p>, which is used for paragraphs. <p> is the main tag used for text, as you can see in the existing html for your page. inside <p> tags you can use <strong> and <em> tags, for bold and italic text respectively. for example, we could write <p>this text is <strong>bold</strong> and this is <em>italic</em></p>

another really important element is <a>, an anchor (link). <a> tags are a bit more complex than <h1> or <p> tags, as they need an href attribute to correctly work, like in <a href="https://neocities.org">Neocities</a>. attributes are extra information we can give to the element, by using the form name-of-the-attribute="content of the atribute" in the opening tag in the case of <a> tags, href (hypertext reference) attributes contain the url to go to when the link is clicked.

another attribute we can add to <a> tags is target. this lets us specify if we want the link to open on the same tab or on a new tab. default behavior is on the same tab, but by adding target="_blank" we can make it open on a new tab, like <a href="https://neocities.org" href="_blank">Neocities</a>:

target blank screenshot

if you save, reload your website, and then click on the neocities link, you'll see how it now opens in a new tab instead of on the same one

another important element is <div>. it allows us to group other tags together, which will be useful when we want to style our page later

something you might have noticed is that all the actual content of your site is inside the <body> tag, but we also have a <head> element that contains some other stuff:

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>The web site of username</title>
    <!-- The style.css file allows you to change the look of your web pages.
         If you include the next line in all your web pages, they will all share the same look.
         This makes it easier to make new pages for your site. -->
    <link href="/style.css" rel="stylesheet" type="text/css" media="all">
</head>

the first two elements are meta tags, which tell the browser extra details about your page. in this case, they're specifying that it uses utf-8, and some details about how zooming and scaling should work.

after that we have the <title> element, which is the text that shows on the browser tab. you can change it to something else, like <title>annieversary!</title>, and if you save and refresh, you should see:

annieversary title screenshot

the last tag in your website's <head> section is <link>, which links a css file to your page. css is how you style your page. we'll talk more about it later

adding content

we'll now add all the content we want to our website. we'll start by removing all of the existing text, and replacing it with:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>annieversary!</title>

    <link href="/style.css" rel="stylesheet" type="text/css" media="all">
  </head>
  <body>
    <h1>im annie!</h1>
  </body>
</html>

this will give us a blank slate to work off of. we'll add two links for now, one to my soundcloud and another to my personal website. of course, you should replace those with links to your soundcloud, twitter, bandcamp, etc.

we'll start by adding an empty <div> tag as a sibling to our lonely <h1>:

  ... other stuff here
  <body>
    <h1>im annie!</h1>
    <div></div>
  </body>
  ... other stuff here

note: i wont show the whole file every time, i'll be only showing the important sections that change

tags are siblings when they live next to each other. in this last code section, both the <h1> and the <div> are children of the <body> tag, and they're siblings between themselves.

we're gonna add some child elements to our empty <div>:

  <body>
    <h1>im annie!</h1>

    <div>
      <h2>
        <a href="https://soundcloud.com/annieversary" target="_blank">
          soundcloud
        </a>
      </h2>
      <p>you can checkout my songs here!</p>
    </div>
  </body>

we've added two children: an <h2> and a <p>. the <h2> tag has an <a> tag as a child. this way, we have a heading and a text element, and the heading will also be a link to soundcloud. in general, most people expect external websites to open in a new tab, so we've added target="_blank" to the link

we'll duplicate the <div> element, but we'll replace the text and link to go to my website, like so:

  <body>
    <h1>im annie!</h1>

    <div>
      <h2>
        <a href="https://soundcloud.com/annieversary">
          soundcloud
        </a>
      </h2>
      <p>you can checkout my songs here!</p>
    </div>

    <div>
      <h2>
        <a href="https://versary.town">
          website
        </a>
      </h2>
      <p>this is my personal website!</p>
      <p>it has some cool stuff!!</p>
    </div>
  </body>

if all is well, your website should now look like the following:

website with two links screenshot

this is cool, but it's very plain. we want our page to be unique! we want to wow people visiting our website! we want to be the most amazing neocities page ever! in my case, i wanna have an early web type of website, with the fun backgrounds, cool text, and all that jazz. to get there, we'll need css

css

css has a bad reputation, but it's not as scary as people make it seem. it has a way of becoming spaghetti if you don't know what you're doing, but we'll try to keep it simple today.

first of all, go back to the neocities dashboard, and open style.css. you'll see the following:

/* CSS is how you can add style to your website, such as colors, fonts, and positioning of your
   HTML content. To learn how to do something, just try searching Google for questions like
   "how to change link color." */

body {
  background-color: white;
  color: black;
  font-family: Verdana;
}

note: the comment is right, anything you might want to do can be easily searched for! i encourage you to experiment and search for stuff you want to do, it's the best way to learn

css files consist of a list of rules. in each rule, we first give it a selector, and then a list of styling properties we want to give to every element that matches that selector, which are contained inside the curly brackets ({}). each property does something different, and there's a lot (A Lot) of them

in the code above, we only have one rule, which has body as a selector, and three properties. the first one, background-color, is pretty self-explanatory. the second one changes the color of text on the page, and the last one, changes the font used. if we replace it with the following:

body {
  background-color: red;
  color: white;
  font-family: 'Times New Roman';
}

our website will now look like this:

red website

note: if you don't see any changes after refreshing, the css file is probably being cached, and you'll need to either clear it (Ctrl+Shift+R), or open the page on an incognito window

now, this is not particularly nice to look at, so we'll change it for something nicer. we'll get a cool background from here, i've picked this one:

image of the background i've selected

download it to your computer, then drag and drop it into the dashboard. you'll have something like:

dashboard with background image

make sure to rename the uploaded image to bg.jpg. with that, we can go back to style.css to add it as a background image. for that, we can use the background-image property:

body {
  background-image: url(/bg.jpg);
  color: black;
  font-family: 'Times New Roman';
}

to indicate where our image is located, we use url, and we give it the path to the image

next, we'll center the text by adding a text-align property:

body {
  background-image: url(/bg.jpg);
  color: black;
  font-family: 'Times New Roman';
  text-align: center;
}

at this point it should look like the following:

text centered cool bg

this could already work as a very plain linktree replacement, but the fun in having your own website comes from the full range of customization it provides! i obviously can't show you every possibility in this post, as it's basically infinite, but i can show you some more stuff. and, as the comment on the css file said, google anything else you want to do! the internet is full of great resources :D

cards

we're gonna make our links be in cards, this way they'll they'll jump out more. for that, we're gonna add classes, which let us be more precise with our css selectors

  <body>
    <h1>im annie!</h1>

    <div class="card">
      <h2>
        <a href="https://soundcloud.com/annieversary">
          soundcloud
        </a>
      </h2>
      <p>you can checkout my songs here!</p>
    </div>

    <div class="card">
      <h2>
        <a href="https://versary.town">
          website
        </a>
      </h2>
      <p>this is my personal website!</p>
      <p>it has some cool stuff!!</p>
    </div>
  </body>

classes are added by adding space-separated words to the class attribute. by adding the classes to those two specific elements, we can now target them in css using .the-name-of-our-class, in our case .card:

body {
  background-image: url(/bg.jpg);
  color: black;
  font-family: 'Times New Roman';
  text-align: center;
}

.card {
  background-color: white;
  width: 30rem;
  margin-top: 3rem;
}

if we instead had used the div selector, all <div> elements on our page would get those style properties applied, which we do not want.

rem are a unit of measurement used in css. we could have used pixels, with px, but rems are nicer to work with since they scale correctly according to the screen resolution

if you reload the page now, you'll see the following:

non-centered cards

that's not really what we were expecting, and here's where the difficulty of computers comes from. computers do what we tell them to do, not what we want them to. we told it to align all text to the center, but we didn't tell it to align the `<div>` elements to the center, so it's left aligning the `<div>`s, and center aligning the text inside them

to fix this, we'll need to add a bit of stuff to the body rule:

body {
  background-image: url(/bg.jpg);
  color: black;
  font-family: 'Times New Roman';
  text-align: center;

  display: flex;
  flex-direction: column;
  align-items: center;
}

with this we have changed the display method to be flex, instead of the default block, and we're making the children be aligned to the center, and to be displayed vertically with flex-direction: column

with that, our cards should look centered! they're a bit bland though, so we'll add some cool borders. i like using broider, which lets you draw by clicking, and then generates a css rule we can add to style.css:

screenshot of broider

i drew a pattern i think is cool, and then i grabbed the .broider rule that's autogenerated for me, and i pasted it into style.css. as a check, here's how that whole file looks like right now:

body {
  background-image: url(/bg.jpg);
  color: black;
  font-family: 'Times New Roman';
  text-align: center;
  
  display: flex;
  flex-direction: column;
  align-items: center;
}

.card {
  background-color: white;  
  width: 30rem;
  margin-top: 3rem;
}

.broider {
    border-image:  url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAABUCAYAAAAcaxDBAAACjElEQVR4Xu2cwVLDMAxE2///aOiJIaHT581Krl2Wq9bW6kmOUxh6v+WnlMC9dLdsdgvQ4iEI0AlAvybkKE4hbdda37MJbU0old4jbq0vQP2mHRgG6BuAVl9c1UeOkHT7lye02xABcePd/gPU7ND5hAXoakBfduhhluJmPfZy8mfFR275s8ZKaOPwN3D9lx9515CPxNvB9R+gJ/7LAT3PBxmkeaL1btzNL9V75RkqJaBqBi6xAB2A+FviAqP1ZEddX/4MzYQeCdgv9tRRitPEdMfJnxW/8gy1EnbTGtjf9V9+5F1DAzW3Slz/Afru99DW8fj0zat/V/jpvLC+AEVEmiBANV6oHgFKtyIm2Vwg1R+g3O0AZUaSIkAlXCyeDlRKyP6nK8g/xQ+GK56hUsLpuDgh+ad4gBZ/FA3Q1YHyodpbMf3I742L3QcoM5IUASrhYvF0oFJC9j9dQf4pnlt+9Vte6uD0+eOE5J/imdDVJ5RnYG/F9AndGxe7D1BmJCkCVMLF4ulApYTsf7qC/FM8t/zqt7zUwenzxwnJP8UzoatPKM/A3orpE7o3LnYfoMxIUgSohIvF5UA5ZRQ/BEb+Lh9cAoEAFWCNSAN0hJKgyb/V3P58uxpdQi/jARqgwvl7LrUm8LFlJrT4s3s50HPfqeM0UrTejbv5pXqvPEOlBFQNHaGCOFmghkn1Bqj+LT458jCib59QMkBxOoLdcfJnxa8ceSthN62B/V3/5UfeNTRQc6vE9R+gu72HquN07rC6XtVX/wKofELVgug9zt2P1gcoERLjASoCI/lyQMkwxasLonwUr36Gy1+ERQYpHqBESIwHqAiM5P8eKAFK/AWB1aZn+2YFaHELA7QY6DcNGRBkDsgg/gAAAABJRU5ErkJggg==") 28 /  28px / 0 round;
    border-width:  28px;
    border-style:  solid;
}

note: that huge blob of text is a base64 encoded image. it's an easy way to store images in a text format

if you now reload the page, you'll notice that the borders don't appear anyway yet. that's because we're using the .broider rule, which applies to elements with the broider class (because of the . at the start of the selector). we can add it to our cards like so: class="card broider". you can have as many classes are you want in your elements, you just need to add a space to separate them

reloading the page should show the following:

cool borders on the cards

images

last thing we'll do is to add an image. i want to show my profile picture at the top of the page. for this, we can use the <img> tag. they take a src attribute, where we can specify a url to the image we want. browsers allow us to write relative paths when using urls to things on our own website. for example, instead of using src="https://username.neocities.org/pfp.png", we can just do src="/pfp.png"

i uploaded my profile picture to the dashboard by dragging and dropping, and then renamed it to pfp.png

i'll put it above the <h1> item:

  <body>
    <img src="/pfp.png" />
    <h1>im annie!</h1>

    <div class="card broider">
      <h2>
        <a href="https://soundcloud.com/annieversary">
          soundcloud
        </a>
      </h2>
      <p>you can checkout my songs here!</p>
    </div>
    
    <div class="card broider">
      <h2>
        <a href="https://versary.town">
          website
        </a>
      </h2>
      <p>this is my personal website!</p>
      <p>it has some cool stuff!!</p>
    </div>
  </body>

you might notice something weird with the image tag. there's no closing tag, and instead of the / being after the < character, it's right before >. this is what we call a self-closing tag. in a nutshell, it's like an opening and a closing tag fused together. it's used on elements that don't have children, like <img>

huge profile picture

now, the image has been added, but it's huuuuge. we can change it's size by, you guessed it, using more css! we'll add a pfp class to the image: <img src="/pfp.png" class="pfp" />. inside style.css, we can create a new rule that sets the width property for this class:

.pfp {
  width: 10rem;
}

finally, my page looks like this:

final page

nothing otherworldly yet, but here's where your own creativity comes in! you now have a base to build on

separator line, for decoration