Sample Video Frame

Created by Zed A. Shaw Updated 2024-12-10 18:57:40

04: Simple Styling

In this module I'll go through many of the common stylistic properties you'll need to start doing basic HTML and CSS pages. There are many CSS properties but we'll start with most direct properties. By direct I mean that changing the property should make an obvious visual change to the HTML element. Other properties can be difficult to see when you change them, so we'll need to use some special tricks later to help with that.

That Border Trick

I give a constant piece of advice when people are learning to code:

Always be printing.

This means that when you have a problem with your code you print everything you can to see inside the program, or use a debugger to help you see how it's running. It's simply too difficult to solve most bugs by simply reading the code repeatedly. You need additional information.

CSS has the exact same problem except the results are visually obscured. Many times you can't figure out what is going on with CSS by simply staring at the webpage. All of the boxes that control CSS are invisible to you by default plus the mechanics behind CSS are far too complex and indirect to reason about them from just the visuals.

You need something similar to printing in CSS, and that "something" is the 1px red border:


p {
  border: 1px solid red;
}

I recommend you add this to CSS rules when you first write them. I try to do this but old habits die hard and I still just go for it, then run into trouble, then add the border later. If you want an easier time then add the border right away, get the CSS right, then remove the border. I also recommend trying other colors like "hotpink" since they are easy to find later and remove with a single search (unless you've got a website that's all hotpink).

Display

The display property is simply the worst. There are 22 different versions of this one property, and many of them are seemingly arbitrary combinations of others that seek to fix the previous versions. My main solution when something is displaying weird is to slap display: block on it and see if that fixes it. 90% of the time that does it, and my research will show that this tag is display:list-item unless it's inside a display: flex then it's display: inline-flex and honestly it's just the worst.

Added to this is that display: inline ignores height and width, which is a great example of CSS's inconsistency. Many times I've tried setting the height or width of something only to find out that it's simply ignoring my commands because someone in 1997 decided that this tag should be inline, not block.

My recommendation is stick to display:block, display:flex, and display:grid for most things, then when you have specific problems look at this list to see which one will work best.

There are also properties that make tags behave like a table, but these are rarely used since you can just use grid or use an actual <table>.

The Display Property Savior

While I say that display in general is a haphazard compendium of codified browser bugs, there are two recent improvements that have helped to redeem CSS:

In this course we will mostly do our layouts using these two display mechanisms as they dodge all of the weird hacky issues found in other display settings.

Width and Height

The most basic property is width and height. This property randomly works depending on where your element is placed, so be careful when you specify it and it doesn't seem to work. In the Display property section of this module I described how different tags (elements) have different default display properties. These properties are very easy to use:

div {
  width: 100px;
  height: 100px;
}

That sets the width and height of all div elements to 100 pixels...probably. Fixed sizes like this should be reliable but many times you'll specify a size and it doesn't really do what you want, especially with the height. You definitely want to use the red border trick to sort out size issues.

Units of Measure

There are many measurement units in CSS now which allow you to dynamically size your elements (among other things). First we get into the absolute measurements, which are mostly for fonts and print media, since they have to deal with real physical sizes:

I find that I don't use these too often, but I will use px for things that are specific sizes. A good example if icons and avatars, which are in specific multiples of 8 on most platforms. I'll have to set 24, 32, 48, 64, and so on since those fit different operating system's icon image guidelines.

The measurements I do use often are the relative measurements, and that's because computer screens come in all shapes and sizes. I think about once every 6 months I get some user with a 32:9 curved gaming monitor complaining that when she "full screens" my website it doesn't work right. It never occurs to her that it's her monitor and not my website that's messed up, but with relative size measurements I at least have a small chance to make this situation usable. I'd say without the relative sizes the 32:9 gaming screen owners would have to do something drastic like...shrink the browser to 1/4 the size of their screen.

Actually, why would you own a monitor that big and then full size everything you see? Weird. Anyway, let's use this as a clear--although insane--example for these sizes.

Keep in mind that when I say "viewport" it's not the monitor size. I'm using the monitor size in these examples since it's from my example above and works to give you a size, but the "viewport" is the part inside the browser where the document is rendered, not the whole screen. That means you have to remove the window "chrome" which is the menu, slider bars, and other things the OS puts on all application's windows.

Margin and Padding

The margin property sets the spacing between two elements, and the padding property sets the spacing inside an element. You can use any of the units of measure you want, but it's usually best to stick to the relative units (em, rem are personal favorites) unless you're doing small changes in size then px works. Finally, both of these come with specific variants for each side of the box:

Padding has the same 4, 3, 2, or 1 unit forms as margin, and this is a common pattern in anything that sets sides to a box. I never remember these so I tend to use these more explicit forms when I need to set only one side:

Again, padding has the exact same specific properties with padding-top, padding-left, padding-right, and padding-bottom.

Fonts

The font property is fairly complex since there's so many fonts with so many names, but the most basic forms are:

Background

The background property can be something as simple as just setting a color, but it also can get very complex with images and positioning those images. You can also repeat background elements to create layered graphics. This is what many "CSS painters" do to create their complex paintings using a single <div>. They're "simply" doing repeated background specifications.

These are the three I use the most, and I think if you need more than that then your idea might be too complex, or you should use the "layer" trick I describe below. I find that background images become far too difficult to control in modern screens with their varying sizes.

The repeat-style can be one of these (taken from the MDN documentation on background-repeat):

Position

Position allows you to change the normal top/down flow of HTML tags, but it's another weirdly designed property with all sorts of footguns. First, let me give you all the property settings then explain why position is sort of broken with a practical example.

top, bottom, left, right

To make the position property work you'll also need to specify it's location using these:

These properties are how you "position relative to" the other tags. The only problem with these is they're inconsistent in what they do depending on how you use them and inside what position setting. I recommend you add the 1px-red-border to both boxes (parent and child), then change these until its right.

Layers, Overlays, and z-index

Remember how I said position is another property that is full of footguns? The reason is the specification says some of these properties do different things depending on their parent's position setting. To me that's simply the worst design and leads to mysterious layout failings because I misspelled "relative" as "reletive". The way a computer program should work is if I say, "this here is positioned relative to the parent," then it's always positioned relative to the parent. If I say something is position: absolute, then it is always position absolute. There should be no weird special cases and exceptions that I have to watch out for.

The situation where you'll most likely run into this is when you want to "layer" an image over something else. According to the description you'd think this would work:

<!DOCTYPE html>
<html>
  <head>
    <style>
      container {
        margin-top: 100px;
        display: block;
        font-size: 3em;
        background-color: #aaa;
        border: 1px solid green;
        height: 100px;
        width: 100px;
      }

      layer2 {
        display: block;
        position: absolute;
        top: 0;
        left: 0;
        border: 1px solid red;
      }
    </style>
  </head>
  <body>
    <container>
      <layer1>A1</layer1>
      <layer2>B1</layer2>
    </container>
  </body>
</html>

This is a full HTML page so you can try this yourself, but what I'm doing here is this:

  1. I create a <container> and two contents for it: <layer1> and <layer2>.
  2. To better see the failing, I'm also moving <container> down 100px by setting margin-top: 100px. If I don't then it'll look like this works when it actually doesn't.
  3. I then want <layer2> to "overlay" (or cover) <layer1>. The effect should be that the letters "B1" cover "A1".
  4. I'm also setting the background-color: #aaa; of <container> so you can see the bounding box easily, and giving it a size of height: 100px; and width: 100px; so it's visible.

If you type this in (you should) and load it you'll see that B1 appears at the very top of the window at position 0, 0. But I told CSS to do position: absolute so shouldn't it be contained inside <container>? No, because of an obnoxious footgun in CSS that none of the pros seem to know about. To make <layer2>B1</layer2> stay inside the <container> we have to set <container> to be position: relative, or anything that's not the default position: static. Using relative seems to work as a good alternative to static, so I use that and then it works:

  container {
    margin-top: 100px;
    display: block;
    font-size: 3em;
    background-color: #aaa;
    border: 1px solid green;
    height: 100px;
    width: 100px;
    position: relative; /* magic! */
  }

Now, there's one more little fix and we need to use something called z-index. Normally when you stack things using position: absolute they will be stacked in a kind of random order. Predicting this order is far too difficult, so what you should do is build the stacks, then if they're wrong fix them with z-index. The alternative is reworking your HTML until its just right (at which point you'll hit something else that makes it fail). With z-index you just set the order and you're done.

This is the process I use when I want to create layers consistently:

  1. Create each element as siblings of a parent tag.
  2. Set the parent tag to position: relative.
  3. Set the children to position: absolute and give them top: 0 or any other coordinates they need.
  4. If they're out of order I then add z-index to reshuffle them.

Lesson Challenge

I'm going to give you a puzzler piece of HTML that you need to type in and make work before you attempt this challenge:

<!DOCTYPE html>
<html>
  <head>
    <style>
      A1 {
        border: 1px solid yellow;
      }

      <!-- your answer here -->
    </style>
  </head>
  <body>
    <A1>
      <B1>red box</B1>
      <C1>blue box</C1>
      <D1>
        <G1>green box <b>blue background</b></G1>
        <H1 id="orange box">orange box</H1>
      </D1>
    </A1>
  </body>
</html>

I've started you off with the CSS you'll have to use to place a border around an element. You know how the selector works, but in the next exercise I'll go deeper into how the property border: 1px solid yellow works and cover many more. For this challenge though you only need to know that putting border: 1px solid red would put a red border around things, and using background-color: blue would make its background blue.

Your challenge is to make boxes and backgrounds that match the text. For example, the <B1>red box</B1> should have a border: 1px solid red to create a red box around it. For the blue background text you'll want to use the property background-color: blue. You'll see what that does later, but for now try to figure out from what you know so far how the background-color might work to solve this puzzle.

Lesson Challenge

I've explained some of the theory behind the CSS rules and you should be trying to play with these while you work through this module. As I mentioned earlier the best way to really learn something visual is to attempt to apply what you learned to copies of other people's websites. In this challenge your task it to find a simple blog that you like and make the best copy you can of it. You don't know about many positioning CSS properties yet, but attempt what you can and see how close you can get with just what you know.

After you copy one site, either do one more copy, or delete this and do this copy one more time. Doing things twice helps you confirm that you actually can do it and that it's not just plain luck. If you did it twice then it's not luck, it's skill. If you can't do it again, then go back and figure out what knowledge you're missing.

Remember to have fun doing this, take your time, and push the accuracy as far as you can. The goal is not to make something perfect, but to learn everything you can from the website you are copying.

Previous Lesson Next Lesson

Register for Learn JavaScript the Hard Way

Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.