Killer Web Development

by Marco Laspe

5.3 Filling and Styling the Layout

In this section we will fill our layout with some life. The goal is not a kick ass new web design, this would be out of the scope of this book and the author's abilities. We will follow the sketches we made in chapter 4.

Creating a better home page

Let's have a look at the homepage sketch from chapter 4.

web application sketches home

We will create this page with HTML and CSS, but before we will change the tests to suite the new home page. First we will extend the index.html file and then change the appearance with CSS. This is the home page from section 5.2:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
<!DOCTYPE html>
<
html>
<
head>
<
title>Microposts On Steroids</title>
</
head>
<
body>
<
h1>Messages With 300 Chars</h1>
<
p>Welcome to <strong>Tukker.Me</strong>, the new way to
tell your friends and the world what you are thinking.</p>
</
body>
</
html>

web2py comes with a HTML framework called Skeleton. Skeleton contains a collection of HTML, CSS and Javascript files which give a boilerplate layout to start your web application. It defines a grid with 16 columns that you can use to create easily your layout.

web application grid skeleton home

First we need to integrate the Skeleton CSS file skeleton.css that lies in the static/css folder of your web application:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
<!DOCTYPE html>
<
html>
<
head>
<
title>Microposts On Steroids</title>
{{
response.files.append(URL('static','css/skeleton.css'))}}
{{include 'web2py_ajax.html'}}
</head>
<body>
<h1>Messages With 300 Chars</h1>
<p>Welcome to <strong>Tukker.Me</strong>, the new way to
tell your friends and the world what you are thinking.</p>
</body>
</html>

If you refresh you browser, you will see how the style of the header and the text change.

web application homepage with skeleton

Let's have a look what we've done:

1.
{{response.files.append(URL('static','css/skeleton.css'))}}

adds the CSS file and :

1.
{{include 'web2py_ajax.html'}}

is necessary for web2py to add the CSS file. It should be always the last web2py statement in the '' element.

web2py views interpret everything that is between the curly braces as Python code - for now just accept, that this is the way to add CSS files in web2py.

Adding the header

In the header we will put the main menu and the name Tukker.Me as the logo. For the logo you could also put some fancy picture in this place, but we want to become web developers - not logo designers:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
<!DOCTYPE html>
<
html>
<
head>
<
title>Microposts On Steroids</title>
{{
response.files.append(URL('static','css/skeleton.css'))}}
{{include 'web2py_ajax.html'}}
</head>
<body>
<header class="container">
<div class="six columns alpha">
<h1>Tukker.Me</h1>
</div>
<div class="ten columns omega">
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Help</a></li>
<li><a href="#">Login</a></li>
<li><a href="#">Privacy</a></li>
</ul>
</nav>
</div>
</header>
<h1>Messages With 300 Chars</h1>
<p>Welcome to <strong>Tukker.Me</strong>, the new way to
tell your friends and the world what you are thinking.</p>
</body>
</html>

The <header> element specifies an introduction, or a group of navigation elements for a HTML document. It was introduced with the HTML5 standard :

1.
<header class="container">

Then we take the first five columns of the <header> and put the logo in it. This is made possible through Skeleton :

1.
<div class="six columns alpha">
  • six columns makes a container with a width of 6 columns of the Skeleton grid.
  • alpha tells Skeleton, that this is the first element in the header - it makes sure, that there is no left margin.

The second element has a width of 10 columns and contains our main menu :

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
<div class="ten columns omega">
<
nav>
<
ul>
<
li><a href="#">Home</a></li>
<
li><a href="#">Help</a></li>
<
li><a href="#">Login</a></li>
<
li><a href="#">Privacy</a></li>
</
ul>
</
nav>
</
div>
  • ten columns again this makes a container with a width of 10 columns of the Skeleton grid.
  • omega tells Skeleton, that this is the last element in the header - this time it makes sure, that there is no right margin.
  • The <a> tag defines a hyperlink, which is used to link from one page to another. The href attribute specifies the URL of the page the link goes to - in our case we just use # as a placeholder, later we will put in real URLs.

If we would make more containers than this two, this container would only have the attribute class="[XXX] columns", where [XXX] stands for the number of columns - no, not adult entertainment.

wrapping the main content

In the next step we will wrap the main content of the homepage in a container and create a register button:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
<!DOCTYPE html>
<
html>
<
head>
<
title>Microposts On Steroids</title>
{{
response.files.append(URL('static','css/skeleton.css'))}}
{{include 'web2py_ajax.html'}}
</head>
<body>
<header class="container">
<div class="six columns alpha">
<h1>Tukker.Me</h1>
</div>
<div class="ten columns omega">
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Help</a></li>
<li><a href="#">Login</a></li>
<li><a href="#">Privacy</a></li>
</ul>
</nav>
</div>
</header>
<section id="main" class="container">
<div class="six columns alpha">
<h1>Messages With 300 Chars</h1>
<p>Welcome to <strong>Tukker.Me</strong>, the new way to
tell your friends and the world what you are thinking.</p>
</div>
<div class="ten columns omega">
<a href="#" class="button">Register</a>
</div>
</section>
</body>
</html>

We wrapped the main content of the homepage with a <div> element, that has the class="container" - just like the <header> element before :

1.
<div class="container">

Again we divide this container in two parts :

1.
2.
3.
4.
5.
6.
7.
8.
<div class="six columns alpha">
<
h1>Messages With 300 Chars</h1>
<
p>Welcome to <strong>Tukker.Me</strong>, the new way to
tell your friends and the world what you are thinking.</p>
</
div>
<
div class="ten columns omega">
<
a href="#" class="button">Register</a>
</
div>

everything should be familiar, except of the class="button" attribute in the <a> tag. The button tells Skeleton to create a neutral looking button.

Ending the page with a footer

Now we will finish the structure of the homepage and add a footer:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
<!DOCTYPE html>
<
html>
<
head>
<
title>Microposts On Steroids</title>
{{
response.files.append(URL('static','css/skeleton.css'))}}
{{include 'web2py_ajax.html'}}
</head>
<body>
<header class="container">
<div class="six columns alpha">
<h1>Tukker.Me</h1>
</div>
<div class="ten columns omega">
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Help</a></li>
<li><a href="#">Login</a></li>
<li><a href="#">Privacy</a></li>
</ul>
</nav>
</div>
</header>
<section id="main" class="container">
<div class="six columns alpha">
<h1>Messages With 300 Chars</h1>
<p>Welcome to <strong>Tukker.Me</strong>, the new way to
tell your friends and the world what you are thinking.</p>
</div>
<div class="ten columns omega">
<a href="#" class="button">Register</a>
</div>
</section>
<footer class="container">
<nav class="sixteen columns alpha omega">
<a href="#">About</a>
·
<a href="#">Terms</a>
·
<a href="#">Contact</a>
</nav>
</footer>
</body>
</html>

The new footer section contains not much new stuff :

1.
2.
3.
4.
5.
6.
7.
8.
9.
<footer class="container">
<
nav class="sixteen columns alpha omega">
<
a href="#">About</a>
·
<a href="#">Terms</a>
·
<a href="#">Contact</a>
</
nav>
</
footer>

The only interesting part is the <footer> tag, it is corresponding with the <header> element. The footer typically contains information about its section such as who wrote it, links to related documents, copyright data, and the like.

Now let's have a look a what we've created.

web application homepage with skeleton

All the elements from our homepage sketch are there. The style looks totally different though. We will deal with the style in the next section.

By the way, this is the look, visibly impaired people would perceive the page through their screen reader. This is why your pages should make sense without styling them through CSS.

Looks like we could commit the code to our repository:

1.
$ hg commit -m"Wrote HTML-structure for homepage"

Adding some style

Right now the homepage of Tukker.Me doesn't look like the next big thing on the internet. We will now add proper styling with CSS, nothing fancy, but it should work fine for us.

Wikipedia says:

Cascading Style Sheets

Cascading Style Sheets (CSS) is a style sheet language used to describe the presentation semantics (the look and formatting) of a document written in a markup language. Its most common application is to style web pages written in HTML and XHTML, but the language can also be applied to any kind of XML document, including plain XML, SVG and XUL.

CSS is designed primarily to enable the separation of document content (written in HTML or a similar markup language) from document presentation, including elements such as the layout, colors, and fonts.[1] This separation can improve content accessibility, provide more flexibility and control in the specification of presentation characteristics, enable multiple pages to share formatting, and reduce complexity and repetition in the structural content (such as by allowing for table less web design). CSS can also allow the same markup page to be presented in different styles for different rendering methods, such as on-screen, in print, by voice (when read out by a speech-based browser or screen reader) and on Braille-based, tactile devices. It can also be used to allow the web page to display differently depending on the screen size or device on which it is being viewed. While the author of a document typically links that document to a CSS style sheet, readers can use a different style sheet, perhaps one on their own computer, to override the one the author has specified.

CSS specifies a priority scheme to determine which style rules apply if more than one rule matches against a particular element. In this so-called cascade, priorities or weights are calculated and assigned to rules, so that the results are predictable.

As we said before CSS is a language for defining styles of HTML documents. The big advantage of using a file for the content and one for the style is, that we can separate the structure of a document from the styling. This makes the whole process less error prone and makes it easier to reuse code.

CSS directives are applied via <tag-name>, class and id selectors:

  • <p>...</p> <-----> p {...}
  • <p class="container"> <-----> .container {...}
  • <section id="main">...</section> <-----> #main {...}

It is also possible to use combinations of the three.

If you remember the last section we already applied classes to the HTML-Code of our homepage. Remember this code? :

1.
<div class="six columns alpha">

This <div> element is member of 3 classes

  • six
  • columns
  • alpha

The styles of these classes are defined in the skeleton.css in line 430 and 473:

  • 430: .container .six.columns { width: 340px; }
  • 473: .column.alpha, .columns.alpha { margin-left: 0; margin-right: 10px; }

Applying our own styles

To apply our own styles we need to create a file static/css/custom.css and tell the layout to use this file. Change the <head> element and put in the following content:

1.
2.
3.
4.
5.
6.
7.
8.
9.
...
<
title>Microposts On Steroids</title>
{{
response.files.append(URL('static','css/skeleton.css'))
response.files.append(URL('static', 'css/custom.css')) <!-- Add this line. -->
}}

{{include 'web2py_ajax.html'}}
...

First we will create the Tukker.Me logo with CSS only. Add the following block to your custom.css:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
header h1 {
font-family: "Ubuntu Sans",Helvetica,Arial,sans-serif;
text-shadow: 0 1px rgba(255, 255, 255, 0.75);
font-weight: bold;
letter-spacing: -1px;
font-size: 28px;
color: white;
background: black;
line-height: 34px;
padding: 0 0 0 5px;
margin-right: 197px;
}

The logo text is captured by the selectors :

1.
header h1

this works because there is one, and only one, <h1> element in the <header>. The block, that is encapsulated by the curly braces, holds the styling properties of the logo text and the corresponding values. A property is the text before the colon, the value is text or number after the colon. Every property-value pair is ended by a semicolon.

logo homepage with pure css

Next we will highlight the links with a different color, that makes it easier for the user to recognize them in the page:

1.
2.
3.
a, a:visited {
color: #009BC2
}

Unfortunately the main menu is still looking like a typical bulleted Powerpoint slide. Luckily web2py comes with a special CSS file to turn list into horizontal menus. This means we need to insert another CSS file to the index.html :

1.
2.
3.
4.
5.
{{
response.files.append(URL('static','css/skeleton.css'))
response.files.append(URL('static', 'css/superfish.css'))
response.files.append(URL('static', 'css/custom.css'))
}}

then add sf-menu class to main menu :

1.
<div class="sf-menu">

Tada, we have some horizontal menü.

Lastly we will reposition the button and add some margin to our content. Add the id="register-button" to the Register button :

1.
<a id="register-button" href="#" class="button">Register</a>

now add the following code to our custom.css:

1.
2.
3.
4.
#register-button {margin: 110px 0 0 10px;}

header.container, footer.container {padding: 20px;}
body > section.container {padding: 0 10px;}

Let's have a look on the homepage.

final app homepage with skeleton

now commit the changes to our repository in the terminal:

1.
$ hg commit -m"finished static version of the homepage"

Books often read by web2py and Python experts:

Comments

  1. For me, the menu changed to horizontal when I gave

      instead of
      .

  2. This only worked for me using

      with no additional
      ...

  3. Everything works fine but the horizontal menu. Anyone an idea why?

Leave a Reply

Required fields are marked *.