Digital humanities


Author: Janis Chinn (janis.chinn@gmail.com) Maintained by: David J. Birnbaum (djbpitt@gmail.com) [Creative Commons BY-NC-SA 3.0 Unported License] Last modified: 2014-03-14T22:53:14+0000


Website layouts

Background

Web design has come a long way since the early days of the internet. Although there are, of course, many ways to pull off a desired layout, these days the go-to technique for arranging panels in a window involves using a combination of <div> elements (to contain the content areas) and CSS styling (to position them). In the past, many used HTML <frameset> elements (now deprecated and scheduled to be eliminated completely from HTML5) and HTML <table> elements to construct their webpages. It’s obvious why frames are no longer a good choice—their deprecated status is reason enough. Tables, on the other hand, might still seem tempting, but it’s frowned upon to use HTML tables to display anything but tabular data, that is, data where the rows and columns both represent values from a range and the cells represents intersections of those values. As HTML moves away from the use of elements for presentational purposes in favor of their use to describe what the data is, instead of what it looks like in a particular view, the usage of any given element is being constrained to those descriptive roles. Your site layout isn’t really a table because the pseudo-rows and pseudo-columns don’t have meaning, let alone systematic meaning, and there are now easier, more representative ways of laying out your site in rectangles.

In your design endeavors, you should always work to make your pages as accessible as possible. This means that ideally they should:

HTML structure and layout

Typically we divide the layout of our webpages into rectangles, each of which will correspond to an HTML element. These rectangles may come in a variety of sizes and can be arranged however you like (and shapes other than rectangles are also possible). The rectangular division of pages is what makes tables such a tempting mechanism for laying out a webpage, but manipulating HTML tables into doing this is, frankly, awful and often requires some mind-boggling nesting of tables. Luckily, we can avoid this tedious fate by using the <div> element. By naming these <div> elements with unique @id attributes, we can then style and position our rectangles in different ways in order to give our page structure. @id attribute values have to be unique in a document; for recurring structural elements within a page (that is, multiple elements that you want to style and position identically), you can use the @class attribute.

A typical webpage that wants to position structural components otherwise than one after another in a single vertical, full-width column will usually have <div> elements for the header, navigation bar, table of contents, main body of the site, and natural divisions within the main body. You might further use <div>s for sidebars, such as to show data side by side with an explanation or description of what’s displayed. The various tales documented on The Annotated Afanas′ev library project showcase how you can use <div>s to create a multi-paned website. Whatever layout you might come up with can almost certainly be created through the application of appropriate CSS styling to a page constructed of <div>s, without recourse to frame or table markup. We refer to these rectangles as panes or panels, rather than frames, to avoid any confusion with obsolete <frame> elements.

Example

As an example of using CSS to control layout we will refer here to the aforementioned Annotated Afanas′ev library project, a collection of Russian fairy-tale texts with linguistic and cultural annotations used for language-teaching. The most common use of these texts by students involves reading the main text in the left frame and clicking on unfamiliar words or concepts, which causes the linguistic or cultural annotations in the right frames to scroll to information about the text that was clicked. Because it might be useful to review new words or concepts in a list (for example, before a test), the associations are backlinked, so that clicking on a headword in the right-side linguistic or cultural panels will cause the main panel, on the left, to scroll to the appropriate location. This means that a user can scroll down either of the right panes and click on an item to view it in context within the main text pane on the left.

The site is built out of separate pages for the individual tales, where each such page consists of four <div> elements: the header, the text (left pane), linguistic commentary (upper right pane), and cultural commentary (lower right pane). These panes scroll independently and, as we mention above, are interlinked, so that clicking on a link in any individual pane scrolls a different pane to the corresponding section. This last feature we will address later, but for now let’s focus on the overall structure. The header stretches the full width of the page, the text pane below it includes a vertical scrollbar and appears to the left of the linguistic and cultural commentary, which are stacked to the right of the page. The HTML looks roughly like this:

<html>
    <head>...</head>
    <body>
        <div id="header">
            <h1>...</h1>
            <hr />
        </div>
        <div id="text">
            <p>...</p>
        </div>
        <div id="ling">
            <h1>Linguistic Commentary</h1>
            <p>...</p>
        </div>
        <div id="culture">
            <h1>Cultural Commentary</h1>
            <p>...</p>
        </div>
    </body>
</html>

Styling with CSS

Once you’ve structured your HTML so that structurally related pieces are grouped together within various <div>s, you must write the CSS that will arrange them within the page according to your design aesthetic. To style the Afanas′ev project, let’s first consider the header.

#header {
    height:65px; /* there’s 20px inherited margin as well, this comes from the overall styling on all obdurodon pages*/
    margin:0;
    padding:0;
}

This piece is fairly straightforward. Since the header is meant to stretch across the page anyway, the formatting here simply handles setting the height, margins, and padding. The height property value here is specified in pixels, which means it will not scale with the page if the window is resized. You must consider whether this is the behavior you want, or whether you would prefer to use percentages or ems, so that as the page stretches and shrinks, the header will follow suit. The margin and padding property values here will aid in making the rest of the page rest flush against the header, keeping the page more tightly laid out.

Next is the <div> for the text of the tale, which spans most of the page horizontally and the rest of the page vertically.

#text {
    position:absolute;
    top:0;
    bottom:0;
    overflow:auto;
    width:73%;
    margin:90px 1em 10px 0; /* top, right, bottom, left */
    padding:0 0 0 0;
    border-right-width:1px;
    border-right-style:solid;
}

By setting the value of the position property to absolute, we gain access to the properties top and bottom (and also left and right, which aren’t used here). In this case, we’ve set both to 0, which means this <div> will sit flush against the top and bottom of the window. The overflow property value is set to auto, which means that scrollbars will appear when necessary, and otherwise will not be displayed. The width property value limits the pane to the specified portion of the screen, leaving room for our remaining two panes. The margin property value lowers the text pane to sit five pixels under the header, keeps the text from sitting flush against the right edge of the window by adding a one-em gap, and fixes it exactly ten pixels from the bottom of the window and flush against the left edge. The last two lines of CSS above create a border along the right side to separate the text pane visually from the linguistic and cultural panes.

The CSS below places the pane for linguistic commentary in the upper right and features a scrollbar that appears when needed, that is, when there is too much text to be displayed all at once in the available space. The length of the tales and extent of the markup are such that this is usually the case, that is, there are usually too many entries to fit in the pane without scrolling.

#ling {
    position:absolute;
    top:0;
    left:74%;
    bottom:0;
    height:60%;
    overflow:auto;
    /* top, right, bottom, left; add 10px to header height create space above scrollable text */
    margin:90px 0 0 1em;
    padding:0;
    border-bottom-width:1px;
    border-bottom-style:solid;
}

We already configured the text pane to extend from the left edge of the screen 73% of the way across, and we now use the left property to position the linguistic pane just past the edge of the text pane, so that it starts 74% from the left edge of the window. It is allotted 60% of the height of the window and granted a scrollbar where necessary, with margins used to position the pane just under the header, as we did for our text pane, and with no bottom margin, so that it sits flush above the cultural pane.

The cultural commentary pane is more of the same, but we will discuss it briefly for the sake of thoroughness.

#culture {
    position:absolute;
    top:60%;
    left:74%;
    bottom:0;
    overflow:auto;
    /* top, right, bottom, left; add to header height and to bottom to create space above scrollable text */
    margin:95px 0 10px 1em; 
    padding:0;
}

Again, this pane is positioned just past the edge of the text pane. It’s positioned directly under the linguistic pane, with the value of the top property set to the height of #ling and a top margin of 95px (90px to match the other panes, and an additional 5 to keep it from running right into the bottom of the linguistic pane).

Other layouts

Before moving on, it’s important to discuss a few other properties that frequently play a role in positioning <div> elements. This will be a brief discussion; for more details you should examine the relevant pages on w3schools:

These are just a handful of the properties you may end up using in laying out your page. We encourage you to explore other properties on w3schools and to examine the source code of sites that include features you admire when building your own project sites.

Scrolling one pane from another

Users of the Afanas′ev site, while reading a fairy tale, may come across a word they don’t know and want to read the linguistic notes on it. That is, they may be operating inside the left pane when they want something to happen in the upper right pane. Conversely, they may be using the site to review vocabulary before a test, reading down the linguistic pane, and they want to see a word in context. Rather than requiring that users scroll tediously to find this information out on their own, or use the generic browser find functionality (which can’t tell which instance of a word you want to find if it occurs more than once), we can link between the appearances of these words across panes. By giving each appearance of this word the same @id in each <div> (with a pane-specific prefix, since @id values have to be unique in the document), we can link simply to that @id, and the page will scroll each pane to display the proper context. For instance, in Волк-дурень (The foolish wolf), the word сторожила in the main text pane has an @id attribute value of text_word3 and an @href attribute value of #ling_word3, while the same word in the linguistic pane has an @id attribute value of ling_word3 and @href attribute value of #text_word3. This means that clicking on the word in the main pane will scroll the linguistic pane to the corresponding word, and vice versa. Remember that the @id is the target of the link, and an @href that points to it has the same value, but with a preceding hash mark (#). Thus, the word in the main pane is tagged as follows:

<a href="#ling_word3" id="text_word3">сторожила</a>

Needless to say, we don’t create those @id and @href values manually! The XML source for these pages contains all of the information in a single file, with the linguistic and cultural markup in line with the text. We use XSLT to create the separate output files, and we use AVTs to construct the attribute values that we use for linking dynamically.

CSS float

The CSS float property has several applications, examples of which can be seen on the course page and in various course projects, e.g.:

Floating an image in text

One use, illustrated on the main course page, floats an image to the right of the page. Even if you resize the window, you can see that the text flows around the image. This is pretty easy to achieve:

<p><img src="float.jpg" class="float" alt="The image to float right" /> Lorem
ipsum dolor sit amet, consectetur adipiscing elit. Nunc nec tincidunt nisi,
hendrerit ultrices augue. Fusce mollis ultricies urna vitae porttitor. Nunc 
eget lectus eu purus egestas commodo.</p>
img.float{
    float:right;
    margin-left:1em;
    margin-right:1em;
}

All that’s necessary is to set the desired element’s float property to right (or left). The margin settings hold the image in a bit from the edges of the page and keep the text from running into the image. This is an easy and common usage of float. This example is rendered below:

[Mike Peel  - Ruins of Whitby Abbey, Whitby, England] Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc nec tincidunt nisi, hendrerit ultrices augue. Fusce mollis ultricies urna vitae porttitor. Nunc eget lectus eu purus egestas commodo. Nulla eleifend sed tellus id volutpat. Proin mattis velit mauris, nec gravida massa rhoncus sodales. Ut mattis blandit leo, at consectetur purus pulvinar nec. Mauris quis interdum nibh. Duis non metus eget libero viverra tempor. Pellentesque laoreet velit dolor, nec feugiat magna placerat id. Proin tincidunt tincidunt ultricies. Morbi porttitor sem at mauris consectetur aliquet. Mauris ac commodo nisi. Mauris cursus diam tellus, vel iaculis mi sollicitudin eget. Curabitur vulputate quis dui ut tristique. Duis elementum lobortis tortor eu imperdiet.

Floating several images

Perhaps instead you want to display multiple images (or other elements) lined up in a row and centered on the page. This turns out to be rather more complicated. For instance to create the following row of images:

left-most imagecenter image(s)right-most image

These images will need to be contained in a <div> with an @id or @class, and you’ll also need to give each image an @id or @class so that you can style them individually. Your HTML should look something like something this:

<div class="images">
    <img class="one" src="english.jpg" alt="left-most image"/>
    <img class="two" src="french.jpg" alt="center image(s)"/>
    <img class="three" src="slovak.jpg" alt="right-most image"/>
</div>

The CSS, then, will look like this:

.images{
    margin-left:auto;
    margin-right:auto;
    display:block;
    width:427px;
}
.images img{
    height:200px;
    margin-left:5px;
    margin-right:5px;
}
.one,
.two{
    float:left;
}
.three{
    float:right;
}

Centering is handled by our first three lines of code. To center anything other than text, set both the left and right margins to auto and display to block. You must also set the width property; in this case, width is set to the sum of the widths of each image (plus margins to keep the images from running into each other). All of this styling goes on the container <div>. Next, we handle the styling that will apply to all our images. The height property is set here because the images in this example are not all the same size. Depending on your project, this may or may not suit your purposes. The left and right margins are set to 5px. We’ve used pixels here so that the width of our <div> will always be correct, even when the window is resized. Finally, we handle getting the images to display all on the same line. In order to keep the text on the page from flowing around the images here, we must set the float property for some of the images to left and some to the right. In this case, the first two images are floated left, while the final image is floated right. Depending on the number of images you are working with, you may need to float more things to the left.

Floating panels

There are a few different methods for floating panels next to each other. On the Caesar project site, the project text is displayed next to a Google Earth map. This is accomplished by floating the <div> containing the map to the left and the <div> containing the text to the right. In order to keep the panels next to each other, each has a width value, and the text panel has an overflow-y property to give it a separate scrollbar. Here are the HTML and CSS needed to achieve this:

<div class="map">...</div>
<div class="text">...</div>
.map{
    width:47%;
    float:left;
    padding-left:2%;
.text{
    overflow-y:scroll;
    width:45%;
    padding-left:1%;
    padding-right:5%;
    float:right;
}

Depending on the structure of the rest of your page, you may or may not need to float the right-hand panel to the right. Often it works just as well simply to float both panels left, as seen on the RuNet site. The difference is often a matter of how closely together the two panels appear, which you can also manipulate by changing the left and right margins. To see this in action, try going to the O. Henry site, bringing up the Inspect Elements panel in your web browser, and changing the value of the float property on <div id="korean"> to left.

Things to keep in mind

Using <iframe>

Suppose you have a two-paned website, and you want to load new content into one pane without having to refresh the entire page. This is the sort of scenario where you should use <iframe>. This kind of approach saves users from having to load more data than they need by keeping all of the current page except the <iframe>, and loading only the new <iframe> content from the server. Furthermore, it lets the browser cache previously loaded data, so that if the user flips back and forth between content, the data doesn’t have to be fetched anew each time from the server.

An <iframe> can take an @src attribute, which specifes the URL of the content to load. If this is left out, the <iframe> will just appear as an empty panel. To load content into that frame, give it an @id attribute and use this @id attribute value as the value for the @target attribute on a link within the page. For example:

<body>
    <div id="links">
        <p>Click a language to read various translations of chapter
            one.</p>
        <ul style="margin-left:40%;">
            <li><a href="en.html" target="read">English</a></li>
            <li><a href="fr.html" target="read">French</a></li>
            <li><a href="de.html" target="read">German</a></li>
            <li><a href="sk.html" target="read">Slovak</a></li>
        </ul>
    </div>
    <iframe id="read" src="en.html"> </iframe>
</body>

In this example, the <iframe> will load the English text by default, and then users can select other languages to view by clicking on the links. The <iframe> has an @id value of read, which must be referred to (using the @target attribute) in any link that should open content within the <iframe>.

<iframe> elements need to be given height and width properties in CSS, or they will not display as you would expect. Aside from this, they behave like any other element and can be styled accordingly. CSS for the example above might look like:

#links{
    float:left;
    width:47%;
}
#read{
    width:45%; 
    margin:1em; 
    position:absolute; 
    top:5%; 
    height:80%; 
    left:50%;
}

The <div id="links"> is floated left and allotted roughly half the screen for its width. The <div id="read"> element is also allotted around half the screen for width, but additionally has its height set to 80% of the screen. It’s absolutely positioned at just past half the screen, and the top and margin properties are set to bring the <iframe> in from the edge of the screen somewhat. You can see a small sample of this code in action below.

The advantage of using an <iframe> instead of a positioned or floating <div> when you’re going to swap in new content is that the <iframe> element takes an @id attribute and is attentive to a @target attribute on a link elsewhere, but that isn’t true of a <div>. If you aren’t going to load new content into the <iframe> dynamically, there isn’t much difference in functionality. We think of the <iframe> as a sort of hole in the canvas; see, for example, the various inner pages on the Twilight princess project. Because the developers wanted the content pane to be sized differently on different pages, they load complete new pages each time, instead of just changing the content of the <iframe>. Nonetheless, the <iframe> feels natural because the text sits in a window inside the larger page (the name of the <iframe> element stands for inline frame.

Beware!

In addition to the <iframe> element, some of you may have heard of the old HTML elements <frameset> and <frame> for designing paneled or windowed interfaces. Remember that those elements have been removed from HTML5 and should not be used for new development.

It’s important to note that XHTML 1.0 Strict removes @target. If you want to use @target, you’ll need to use XHTML 1.0 Transitional or HTML5 in order to have valid HTML. You can read more about this on the W3C site.

Though they work somewhat similarly insofar as they insert content from one file into a page that is otherwise the content of a different file, you should not use <iframe> elements where you could instead use server side includes (SSI). SSI is more transparent to the end user, and makes site navigation more straightforward. Abuse of <iframe> elements can be confusing to the user, as it makes it unclear what will happen when using the back button.

Although <iframe> elements can be used effectively, keep in mind that they also represent a potential security risk in situations where you have your <iframe> load content from an external site, one that you don’t control yourself. Pulling content from another site means trusting the code on this other site not to infect your users, to link to similarly trustworthy sites, and to stay up indefinitely. Instability is a more likely risk than malice; if you link to content on an external site and it is taken down someday, that will leave your site with broken pages without warning. We’ve become used to the risk of broken links, where the user clicks and gets an error message, but in that case at least your original page looks intact. If your original page contains an <iframe> that pulls content from a site that goes down, the damage winds up painted on your page, and not just on the other end of a clickable link.