Menu Tabs (Part 2)

2009 July 4
by Joe

Drawing from the previous tutorial, I want to place the menu tabs in the following arrangement.

menu_tab_s8

Working from the outside in, let’s position the page content. In the following HTML document, I’ve assigned ids to two elements.

  • A container – This constrains the width of the page and centers it.
  • The page – Houses the banner and page content
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    <body>
        <div id="container">
            <div id="page">
                <p>The page content will be placed here.</p>
            </div>
        </div>
    </body>
</html>

Here is the corresponding style sheet named style.css:

body {
        background-color: #334;
}

#container {
        /* Centers on the page */
        margin: 0 auto;
        /* Width of container */
        width: 500px;
}

#page {
        background-color: #fff;
        border: solid 1px #000;
        padding: 0 10 0 10px;
}

The # directive targets an id. For example, #page looks for an html tag with an id of page and applies the style to it.

To center container I had to use margin: 0 auto;. Using text-align: center does not work as this centers the content within the container.

The four numbers in padding: 0 10 0 10px; correspond to padding top (north), right (east), bottom (south) and left (west), respectively.

This gives us the following web page. Everything outside of the page content is filled in with a dark grayish-blue color.

menu_tab_s9

Adding the header image, we could place an img tag within the page div, but let’s using CSS to accomplish this.

Modify the html page to use another div with an id of header.

                <div id="container">
                        <div id="header">

                        </div>
                        <div id="page">

The header graphic that I’m working with has a height of 122 pixels and a width of 596 pixels. The width of the container is 500 pixels and will truncate anything to the right of it.

Add the following CSS style:

#header {
        background: url('131.jpg') no-repeat -25px;
        height: 122px;
}

This gives us a header image:

menu_tab_s10

All that is remaining is adding the menu tabs and we are done. Including the menu_tabs.css file from the previous tutorial and change the tab labels slightly we have.

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="style.css">
        <link rel="stylesheet" type="text/css" href="menu_tabs.css">
    </head>
    <body>
        <div id="container">
            <div id="header">
                <ul class="menu_tabs rounded_top beige_tabs">
                    <li>Donald</li>
                    <li>Mickey</li>
                    <li>Goofy</li>
                </ul>
            </div>
            <div id="page">
                <p>The page content will be placed here.</p>
            </div>
        </div>
    </body>
</html>

And…

menu_tab_s11

We need to move the tabs to the bottom of the header image. Using vertical-align: bottom; did not produce the desired result. I had to scour the internet for the correct solution which is:

  • Give the div housing the element in question relative positioning.
  • Move the element to the bottom by giving it absolute positioning locating it at the bottom.

Without giving the housing element relative positioning, the menu tabs will be forced down to the bottom of the web page. I added height: 100% to the #page style (not shown below) to expand the page into fill the entire document to the bottom of the screen.

#header {
    background: url('131.jpg') no-repeat -25px;
    height: 122px;
    position: relative;
}

.bottom {
    bottom: 0px;
    margin: 0 0 0 -20px;
    position: absolute;
}

Add the style to the even-growing classes listed in the ul tag.

<ul class="menu_tabs rounded_top beige_tabs bottom">

Now, the menu tabs appear in the correct position.

menu_tab_s12

Source files: menu_tabs_20090704.zip

Menu Tabs

2009 July 2
by Joe

This tutorial will take a bland, unordered list and through the magic of CSS (Cascading Style Sheets) manipulation, turn these into curved menu tabs that run lengthwise along the page. Keeping things simple, I will use CSS version 3 features to make the tabs curved, supported by Firefox and Safari 3.0 or later.

<html>
        <head>
                <link rel="stylesheet" href="menu_tabs.css">
        </head>
        <body>
                <ul>
                        <li><a href="#">Tab A</a></li>
                        <li><a href="#">Tab B</a></li>
                        <li><a href="#">Tab C</a></li>
                </ul>
        </body>
</html>

The above file contains an unordered list of elements and displays on a web page as follows.

menu_tab_s1

I am going to control the appearance of the unordered list by adding a class attribute to the ul tag.

<ul class="menu_tabs">
    <li><a href="#">Tab A</a></li>
    <li><a href="#">Tab B</a></li>
    <li><a href="#">Tab C</a></li>
</ul>

The unordered list has a style class of menu_tabs. The menu_tabs style is defined in a file named menu_tabs.css.

.menu_tabs {
        /* Turn off bullet points */
        list-style: none;
}

.menu_tabs a {
        /* Turn off underlining html links */
        text-decoration: none;
}

After saving the stylesheet, the web page looks like.

menu_tab_s2

To make the list run horizontally across the page, I will use the float style and add a margin separating each element. The px mentioned in the style below is an abbreviation for pixels.

.menu_tabs li {
        float: left;
        margin-right: 5px;
}

The list of items appear horizontally.

menu_tab_s3

Define a rectangular border and add some space, or padding, between the border and text. Modify the existing .menu_tabs li style to:

.menu_tabs li {
        border: solid 2px #000;
        float: left;
        margin-right: 5px;
        padding: 5 15px;
}

Now, we have some menu tabs.

menu_tab_s4

To make the tabs rounded using CSS3, we will use vendor specific CSS styles. Sadly, browsers want diverge when it comes to rounding corners.

Note: The curved borders will not render in Internet Explorer. The same also applies to using hover used later.

Firefox Safari
-moz-border-radius-topleft -webkit-border-top-left-radius
-moz-border-radius-topright -webkit-border-top-right-radius
-moz-border-radius-bottomleft -webkit-border-bottom-left-radius
-moz-border-radius-bottomright -webkit-border-bottom-right-radius

I want to make the top of the border rounded. So, I will create a new style definition and supply the Firefox and Safari properties to it.

.rounded_top li {
        -moz-border-radius-topleft: 10px;
        -moz-border-radius-topright: 10px;
        -webkit-border-top-left-radius: 10px;
        -webkit-border-top-right-radius: 10px;
}

Next, I will add rounded_top to the class attribute.

<ul class="menu_tabs rounded_top">
    <li><a href="#">Tab A</a></li>
    <li><a href="#">Tab B</a></li>
    <li><a href="#">Tab C</a></li>
</ul>

The tabs are now rounded at the top.

menu_tab_s5

Let’s give the tabs some color. Since the text contained in each tab is an href link, I also need to supply a style definition .beige_tabs a to change its color.

.beige_tabs li {
        background-color: #ffe;
        border: solid 2px #cb9;
        color: #875;
}

.beige_tabs li a {
        color: #875;
}

Adding the beige_tabs style to the growing class attribute we have:

<ul class="menu_tabs rounded_top beige_tabs">
    <li><a href="#">Tab A</a></li>
    <li><a href="#">Tab B</a></li>
    <li><a href="#">Tab C</a></li>
</ul>

The menu tabs now look like this:

menu_tab_s6

To make a tab change color when we place our mouse over it, we will need dive into the css file and add two more styles. Internet Explorer does not understand the hover keyword and ignores the style.

.beige_tabs li:hover {
        background-color: #cb9;
        color: #ffe;
}

.beige_tabs li:hover a {
        color: #ffe;
}

At produce the desired mouse-over highlighting, I had to place the class attributes at the ul tag instead of on each li tag. The hover property, which only works in later browsers, is activated when any part of the tab is touched. In the screen capture below, the mouse is positioned over Tab B.

menu_tab_s7

Source files: menu_tabs_20090702.zip

An Id Without a Name

2009 June 27
by Joe

Yes, you are shaking your head, thinking that Internet Explorer (IE) 8 is the latest web browser, but web applications created four or five years ago are expected to operate using the web browser used during that time, Internet Explorer 6.

So, here is one of the many Internet Explorer 6 oddities.

When dynamically creating form inputs, you can assign an id to it; however, Internet Explorer 6 does not support assigning a names to them as form names are considered a read-only property. Consider the following JavaScript function that create and attaches a text element.

function addTextElement(appendElement, name, id, value) {
    var textElement = document.createElement('input');
    textElement.type = 'text';
    textElement.name = name;
    textElement.id = id;
    textElement.value = value;

    appendElement.appendChild(textElement);
}

The textElement.name does nothing. Below is code that uses the above function to dynamically create a form element and attach it to a form, my_form.

function onLoadHandler() {
    var formRef = document.forms.my_form;
    addTextElement(formRef, 'element_name', 'element_id', 'element_value');

    alert(formRef.innerHTML);
}

The alert reveals that the form element in question has an id, type and value; however, it lacks a name. Code operating in IE6 has to reference the form element by id.

What’s the oddity? When the form is submitted to the web server, the name appears on the other side.

To reference the dynamically created element name in IE6, the name needs passed into the createElement method as shown below. Only then will you be able to reference the form element by name.

function addTextElement(appendElement, name, id, value) {
    var textElement = document.createElement("<input type='text' name='" + name + "' id='" + id + "' value='" + value + "'>");

    appendElement.appendChild(textElement);
}

Day of Ruby (Part 3)

2009 May 20
by Joe

Due to difficulties getting Cucumber working on three different operating systems and various versions of Ruby gems, the next two sections were rather accelerated.

The next topic that Cory discussed involved creating client applications with a basic UI tool kit called Shoes.

Three shoe applications were shown: a simple button click application, a simple Hello World application using a stack and a more complicated binary clock.

Here’s the source code for the Hello World application using a stack. Stacks are used to organized layouts. In Java AWT (abstract window toolkit) terms, it is similar to a panel. It servers as a container that holds UI components and displays them by specified layout.

File: layout.rb

Shoes.app do

  background '#EFC'
  border 'BE8', :strokewidth => 6

  stack(:margin => 12) do
    para 'Enter your name'

    flow do
      @name = edit_line
      @ok = button 'OK'
    end
  end

  @ok.click do
    @name.text = "Hello #{@name.text}"
  end

end

Executing this application using Shoooes displays (without the name Joe pre-filled):

shoooes_20090520