CHAPTER 26

THE CSS DOJO

TIME LIMIT: 10 HOURS

This project is called The CSS Dojo because it gives you room to practice your budding CSS and HTML skills. You will now extend what you’ve learned about building webpages and build a web application, complete with four HTML pages and five CSS stylesheets (the fifth stylesheet for styles shared amongst the HTML pages). At the end of the project, you will be left with a multi-page deployed website that you can extend or replicate as you continue your coding journey.

A New Project

It’s a new day. You just handed off the Alice’s Restaurant project to your other team members. The Engineering Manager and The Designer walk in.

You: Good morning! So what are we building next?

Engineering Manager: You did a great job on the Alice’s Restaurant project. Now we’ve got a new project - The CSS Dojo. It’s going to be a long-term project where we build an educational webpage to show off our front-end engineering chops. We’re going to show off just how much CSS we know! Whoop whoop!

The Designer: We’re going to be actively working on this going forward. We want you to start working on the prototype. After getting some user feedback, we will iterate on the design.

Engineering Manager: Yep. Anyways, show The Coder the designs?

The Designer: OK, this is the landing page of the Dojo: pretty easy stuff.

Turn this into `index.html`.

The Designer: Pretty simple. We’ll send you the CSS3 logo there as a file (along with the other images). Also, can you make the navigation links pop on hover? Maybe make the text a little bigger on hover?

You: writing in Coding Journal No problem.

The Designer: Here is the second page, the images page. It has two panels

Turn this into `images.html`.

The Designer: This has a nice big splashy image in the top panel. Make it take up about 90-95% of the browser viewport when it loads. I want the second page to peek up, so the user knows to scroll down.

You: Got it.

The Designer: Here is the third page, the forms page. It’s got one panel.

Turn this into `contact.html`.

Engineering Manager: Nothing fancy here. Just skin it out. I will have the JavaScript Engineer take over the form submission.

You: Actually, styling that checkbox to look like that is a decent amount of work, especially without a CSS library. Have we picked out a CSS library to work with? Everything else you’ve shown me to do seems pretty simple, but that would take me, like, four hours to do. And if we might be iterating on the style, that seems like a bad use of engineering resources because we may get rid of it. Also, some browsers override your CSS on checkboxes anyway.

Engineering Manager: That’s a good point; I know that styling forms can be a lot of work. Just make it look decent today, then we will revisit the checkbox issue another day. I don’t want one little styling issue to hold this product up. We will just take some technical debt here.

Engineering Manager: Next page.

The Designer: Here’s the fourth page - on CSS positioning. A picture is worth a thousand words, so we’re just doing this barebones demonstation page. This has three or four panels (or more), depending on how you want to look at it.

Turn this into `positioning.html`

Engineering Manager: Any questions?

You: Do you want me to make this page responsive?

Engineering Manager: For now, just make the desktop version of the website.

You: Got it. If you send me the image files, I will send you a link to a GitHub Pages site by the end of the day.

Making Your Plan

As always, start by thinking about the project and making a plan before acting. We will use our standard GitHub Pages deployment. We have mockups for four pages and few other requirements. How do we translate the mockups into a software product we can ship on GitHub Pages?

Project and File Structure Planning

Since we know what we’re doing to deploy, let’s begin by planning the project/file structure.

We need to build four pages. This means we are going to make at least four HTML documents - one for each of the four mockup pages we received.

How many CSS documents do we need? Consider a few choices:

  • Option 1: One big stylesheet - import it into all four pages. This isn’t a terrible option for the pages we have to build today… but the other team members said this is going to be a long-term project. Better to give each page it’s own stylesheet.
  • Option 2: One stylesheet per page. A less compelling option, given that all of every page has at least two styles in common. What if The Designer decides to use a different background color, other than that blue one? You would have to go change the style on every stylesheet. Easy to miss something and make a mistake.
  • Option 3: One stylesheet with common styles, then one stylesheet for each page with their individualized styles.

Option 3 is the clear winner. The first two options violate a primary law of software – DRY: Don’t repeat yourself.

So now, count them up: four HTML pages, five stylesheets. We will leave the HTML files in the root folder of the project, and put all the stylesheets in a styles folder. But what about assets - those images The Designer is sending? Let’s put them in an images folder.

Now we know which files we need.

Coding, Testing, and Deployment Process

Once we have all of the files set up and linked together, we can follow our standard routine for each webpage in our web application:

  1. Diagram the layout of the page - draw your boxes!

  2. Turn those boxes into HTML - get the content into the HTML document with proper markup.

  3. Write the CSS that styles the HTML.

  4. Test the results of the previous steps with a local HTTP server. Add any bugfixes and/or improvements, then test again.

  5. Deploy and test. Add any bugfixes and/or improvements, then deploy again.

Repeat steps as necessary. Use version control throughout entire process.

Enough planning. Time to code.

Setting Up Your Git Repository

Navigate to github.com and set up a new repository called the-dojo. Click the “Initialize with a README” option.

Then, using the command line, clone the project to your desktop and cd into it.

cd ~/Desktop
git clone https://github.com/kevmo/the-dojo
cd the-dojo

Setting Up Your File Structure On The Command Line

Time to set up the plumbing of our application - the initial directory and file structure. Create the four HTML pages, the two folders, and the five CSS pages.

touch index.html contact.html positioning.html images.html
mkdir styles && cd styles
touch styles.css
touch index.css contact.css positioning.css images.css
cd ..
mkdir images

Your project thus has the following file structure (as seen from its root level):

- README.md
- index.html
- contact.html
- positioning.html
- images.html
- images/
    - <currently empty>
- styles/
    - styles.css
    - index.css
    - contact.css
    - positioning.css
    - images.css

Go download/copy the image files from https://github.com/kevmo/the-dojo/tree/master/images and put them in your own images folder.

Save your work.

git status
git add .
git commit -m "Initial folder and file structure."
git push origin master

You are now ready to begin coding. Open the-dojo project in your text editor.

Coding Common Files and Patterns

Let’s start by recognizing the common structure of each of the HTML pages. Every single one of the HTML pages contains a lot of the same code (especially in the HEAD section). Code the common parts once, ensure it is working, then you can copy-paste code into the other three HTML files.

Let’s start with the skeleton code of index.html. We will link to two stylesheets - Normalize.css (which removes browser CSS presets) and our generalized styles.css. Each page will link to these same two stylesheets (and an individualized one of their own, for a total of three stylesheet links per page) To make sure we have our pages linked together properly, let’s go ahead and create styles.css.

In your text editor, write these 12 lines into index.html:

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css">
    <link rel="stylesheet" href="styles/styles.css">
    <title>CSS Dojo</title>
  </head>
  <body>
     <h1>index</h1>
  </body>
</html>

To make sure this markup works, test it by running python -m http.server and navigating to http://localhost:8000 in your browser. You should just see the word “index” in the body.

To make sure we’ve inserted the generalized stylesheet styles.css correctly, let’s add some CSS rules to it:

html {
  background-color: RGB(66, 146, 238);
  font-family: Helvetica;
}

h1 {
  font-size: 4.5em;
  text-align: center;
  color: white;
  font-style: italic;
  text-transform: uppercase;
  text-shadow: 4px 4px 4px black;
  letter-spacing: 3px;
}

Open the page in the browser again. It should now have a blue background and “index” should be big, white, italicized, and in the center of the page.

If that is the case, save your work.

git status
git add index.html styles/styles.css
git commit -m "Skeleton HTML page and generalized styles document."
git push origin master

Now copy the contents of index.html into contact.html, images.html, and positioning.html. Instead of “index” in the H1 tag, write “contact”, “images”, and “positioning”, respectively. This will provide a helpful visual clue for testing.

Test, Iterate, Deploy

Start the Python HTTP server from the project root. You should know be able to see unique pages at localhost:8000 using the URL paths /contact.html, /images.html, and /positioning.

At http://localhost:8000/positioning.html.

Save your work:

git status
git add positioning.html contact.html images.html
git commit -m "Stubbed out the HTML pages and styles.css."
git push origin master

And now do your first deploy with GitHub pages. Smart developers test their deployment processes early and often.

git checkout -b gh-pages
git push origin gh-pages

Go examine all four pages at http://.github.io/the-dojo. The same URL file paths will apply to that host as they do locally. Ensure that all four pages exist as you expect them to at the URLs you expect them to be at.

Coding Each Individual Page

Switch back to your master branch. We are not using feature branches because 1) we are the only one working on this project at the moment, and 2) we are also still basically in set-up mode.

git checkout master

The Landing Page

Using your text editor, edit index.html. We will need to add a link to that page’s individualized stylesheet in the HEAD. Add this link tag after the two link tags that are alredy in the page

<link rel="stylesheet" href="styles/index.css">

Now edit the BODY portion of the page to contain the landing page’s content. At the end of it all, your index.html file should be these 21 lines:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css">
    <link rel="stylesheet" href="styles/styles.css">
    <link rel="stylesheet" href="styles/index.css">
    <title>CSS Dojo</title>
  </head>
  <body class="landing">
    <img src="images/css3.png" ="CSS3 log">
     <h1>The CSS Dojo</h1>
     <h2>What would you like to learn about today?</h2>
     <ul>
       <li><a href="positioning.html">positioning</a></li>
       <li><a href="images.html">images</a></li>
       <li><a href="contact.html">forms</a></li>
     </ul>
  </body>
</html>

Now add its individualized styles in index.css:

.landing {
  color: white;
  text-align: center;
}

.landing img {
  width: 6em;
  margin-top: 3em;
}

.landing h2 {
  letter-spacing: 1px;
}

.landing li {
  letter-spacing: 1px;
  text-decoration: none;
  list-style-type: none;
  min-height: 2em;
  font-size: 1.4em;
}

.landing li:hover {
  font-size: 1.6em;
}

.landing a {
  text-decoration: none;
  color: white;
}

Although we don’t strictly need to at this moment, we are using the .landing class to create descendant selectors. This is good CSS hygiene - if we later decide to combine stylesheets, these styles will still be localized to just the landing page.

Test Iterate, Deploy

Run your Python server command and look at the homepage you just built. Do the links work? Does it behave as expected? If so, save your work in the master branch, then merge that work into the gh-pages branch and deploy again.

git status
git add index.html styles/index.css
git commit -m "First draft of landing page complete."
git push origin master
git checkout gh-pages
git merge master
git push origin gh-pages

After GitHub’s servers have had a minute to update and serve your page, go check your GitHub Page - make sure the page is working as you expect.

We will follow a similar workflow for the rest of the pages.

The Images Page

Switch back to the master branch and code the images page now:

git checkout master

In the text editor, edit images.html to look like the following:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css">
    <link rel="stylesheet" href="styles/styles.css">
    <link rel="stylesheet" href="styles/images.css">
    <title>CSS Dojo</title>
  </head>
  <body class="images">
    <div class="top">
      <h1>how to use images</h1>
      <p>1. Set them with the CSS background-image property.</p>
    </div>
    <div class="bottom">
      <p>2. Use an HTML &lt;img&gt; tag.</p>
      <img src="images/cat.png" alt="adorable kitten">
      <img src="images/cat.png" alt="adorable kitten">
      <img src="images/cat.png" alt="adorable kitten">
      <img src="images/cat.png" alt="adorable kitten">
      <img src="images/cat.png" alt="adorable kitten">
      <img src="images/cat.png" alt="adorable kitten">
    </div>
  </body>
</html>

Make images.css as follows:

.images .top {
  background-image: url(../images/bike.png);
  background-size: cover;
  height: 95vh;
  width: 100vw;
  position: relative;
  background-repeat: no-repeat;
  width: 100vw;
}

.images h1 {
  margin-top: 0;
  padding-top: 2em;
}

.images p {
  font-size: 1.4em;
  letter-spacing: 1.3px;
}

.images .top p {
  position: absolute;
  bottom: 1em;
  left: 3em;
}

.images .bottom p {
  position: relative;
  top: 1em;
  left: 3em;
  margin-bottom: 4.5em;
}

.images img {
  width: 15%;
  margin: 3em 0 0 4em;
}

Test Iterate, Deploy

Again, run your HTTP server from the project root. Does everything at localhost:8000 and localhost:8000/images.html look as it should? If so:

git status
git add images.html images.css
git commit -m "First draft of /images page."
git push origin master
git checkout gh-pages
git merge master
git push gh-pages

Now go examine the GitHub page. Fix bugs as necessary.

The Form Page

Again, on the master branch.

Make contact.html:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css">
    <link rel="stylesheet" href="styles/styles.css">
    <link rel="stylesheet" href="styles/contact.css">
    <title>CSS Dojo</title>
  </head>
  <body class="contact">
     <h1>sign up form</h1>
     <form action="#" method="#">
      <input type="text" placeholder="Name">
      <input type="email" placeholder="Email">
      <input type="password" placeholder="Password">
      <div class="checkbox-container">
        <input type="checkbox" id="newsletter" checked>
        <label for="newsletter">Receive Weekly Newsletter</label>
      </div>
      <button type="submit">Submit</button>
     </form>
  </body>
</html>

Make contact.css:

.contact {
  color: white;
}

.contact h1 {
  font-style: normal;
}

.contact input:not([type=checkbox]),
.contact .checkbox-container,
.contact button {
  display: block;
  width: 30%;
  margin: 0 auto;
  margin-top: 1.3em;
  border-radius: 20px;
  height: 2em;
}

.contact input:not([type=checkbox]),
.contact button {
  display: block;
  width: 30%;
  margin: 0 auto;
  margin-top: 1.3em;
  border-radius: 20px;
  height: 2em;
  text-indent: 1.5em;
  background-color: RGB(170, 193, 221);
  border: 1px solid white;
}

.contact input[type=checkbox] {
  display: inline-block;
}

.contact input[type=checkbox]:checked {
  background-color: RGB(170, 193, 221);
}

.contact button {
  width: 10%;
  text-indent: 0;
  color: white;
}

Test, Iterate, Deploy

Follow the same procedure as before:

  • Test the code using your local HTTP server
  • Ensure that http://localhost:8000/contact.html looks as you intend
  • Save to the master branch (git add . and git commit -m <MESSAGE>)
  • Update the gh-pages branch (git checkout gh-pages && git merge master)
  • Push both branches to the origin repository (git push origin <BRANCH-NAME>)
  • Test the GitHub Page
  • Repeat steps as necessary.

The Positioning Demo Page

The final page! Almost there. Don’t let fatigue affect your git hygiene - git checkout master.

Code the positioning.html document:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css">
    <link rel="stylesheet" href="styles/styles.css">
    <link rel="stylesheet" href="styles/positioning.css">
    <title>CSS Dojo</title>
  </head>
  <body class="positioning">

    <header>Fixed - fixed in place place on the browser window</header>

    <div class="panel one">
     <h1>positioning demo</h1>
     <div class="box">
       <strong>Static</strong>
       <ul>
         <li>default</li>
         <li>appears in ordinary flow of document</li>
       </ul>
     </div>
   </div>

   <div class="panel two">
    <div class="box">
      <strong>Relative</strong>
      <ul>
        <li>position the element relatively to where it would statically appear</li>
      </ul>
    </div>
  </div>

  <div class="panel three">
    <div class="box">
      <strong>Absolute</strong>
      <p>Element is positioned relative to first non-static containing element.</p>
    </div>
    <div class="box">
         <strong>Absolute</strong>
         <p>Element is positioned relative to first non-static containing element.
     </div>
     <div class="box">
      <strong>Absolute</strong>
      <p>Element is positioned relative to first non-static containing element.</p>
    </div>
 </div>
  </body>
</html>

Your final stylesheet at positioning.css:

.positioning header,
.box {
  background-color: RGB(222, 255, 44);
}

.positioning header {
  position: fixed;
  height: 3em;
  width: 100vw;
  top: 0;
}

.positioning > .panel {
  height:60vh;
  border-bottom: 2em solid RGB(222, 255, 44);
}

.positioning h1 {
  padding-top: 1em;
}

.box {
  height: 10em;
  width: 10em;
}

.two .box {
  position: relative;
  top: 5em;
  left: 10em;
}

.three {
  position: relative;
}

.three .box {
  position: absolute;
}

.three .box:first-child {
  top: 1em;
  left: 1em;
}

.three .box:nth-child(2) {
  bottom: 1em;
  left: 1em;
}

.three .box:nth-child(3) {
  right: 1em;
  top: 1em;
}

Test, Iterate, Deploy

Follow the same procedures as before.

Add a README

It is important to document your work. Add the following to your README.md file:

The CSS Dojo project exists as a demostration of applied CSS concepts,
both basic and advanced. You can visit it at <INSERT-URL-HERE>.

To demo on this project locally, clone it, then run `python -m http.server` (Python 3) or `python -m SimpleHTTPServer` (Python 2).

Add this to your master branch and push to the origin repository. You should be able to see the README description at https://github.com//the-dojo. READMEs are incredibly handy and will help you (and others) understand a project for future use.

Recap

This is the most complicated site you’ve built with this book so far. You took an entire web application from mockup to deployed. You continuously deployed the entire time. You got more experience with HTML and CSS. You saw how different files are imported into each other from the same server.

You can see a final version of my working site at https://github.com/kevmo/the-dojo.

As you work through the rest of the CSS book, I recommend that you either extend the The Dojo webpage or, better yet, start new projects (more GitHub repositories) from scratch. The more times you experiment with the workflow and webpages, the better coder you will become. Every single tutorial in the CSS book presents you with an opportunity to better learn core technologies and build your GitHub resume.

Exercises

  1. What is a relative path? Where did we use one on the images page? Look at the Network tool in the developer tools and see how the browser interprets these relative path URLs.

Reminder: You read about relative paths in Chapter 3 of The Linux Book.

  1. Read/skim Chapter 8 of the CSS book, “Adding Graphics to Web Pages”. Use the /images.html page you just built to experiment with what you read about. Try adding more panels, resizing the images, changing the properties, etc.

  2. Read/skim Chapter 14 of the CSS book, “Positioning Elements on a Web Page”. Use the /positioning.html page you just built to experiment.

  3. Read the second half of Chapter 11 of the CSS book, “Formatting Tables and Forms” (you can skip the part about tables). Use the /contact.html page as a playground for your studies.

  4. The only way to get good at writing HTML and CSS is to write a lot of it. Congratulate yourself on taking a big step in this journey with this long project.