Ramblings on HTML Page Structure and Bootstrap
Tags: css, webdev, design, html
Published: 2024-01-06 15:32:06

When people talk about the [Bootstrap CSS framework](https://getbootstrap.com/), the conversation usually revolves around CSS classes: there is this class and that class, and this is how to display a primary button on a webpage.

However, Bootstrap is, essentially, a declarative language. It describes how a web page is supposed to look like.

In a sense, regular HTML/CSS describe the same thing, but on a lower level: they define block elements, inline elements, and how you can position them on a page. Bootstrap is a higher-level language typically used to describe webpages in more generic terms.

## Structure of a webpage

If you take a look at the typical homepage of almost any website, you'll see they all have a similar structure. First comes the menu, followed by several sections containing the main content, and then the footer.

How is it expressed by the bootstrap? 

In Bootstrap, the menu is a special and probably the most complex component. Bootstrap features a horizontal dropdown menu that, on smaller screens, is replaced by a vertical menu with a hamburger button. The Bootstrap menu deserves its own separate discussion, which I won't go into right now.

Following the menu are several page sections. A section is essentially a horizontal band containing various elements. Usually, you need to define the distance between this section and the previous one.

How can we describe this, loosely drawing on an analogy of objects with properties and values?

## Section

If we were to define 'Section' as an object with properties, it would look like this:


```yaml
Section:
    name: Product Features
    margin-top: 3
    margin-right: 0
    margin-bottom: 3
    margin-left: 0

```

And this is how it is done in bootstrap:

```html
<section class="product-features my-3">
```

The "my-3" class specifies vertical margins (along the 'Y' axis) - both top and bottom margins - with a value of '3' on Bootstrap's spacing utility scale. This scale ranges from 0 to 5, where '0' implies no space between sections and '5' indicates maximum spacing, creating a significant gap. Thus, '3' provides a moderate amount of vertical space, ensuring the sections are neither too close nor too far apart. 

If your perception of 'very far apart' differs from that of the Bootstrap creators, or if you need more steps to define your own distance scale, you have the option to customize it yourself. 

Continuing with the 'Section' object from our earlier analogy, you set the values for its 'margin-top' and 'margin-bottom' properties in this way.

Now that we have placed a section on the page, we can concentrate on what's inside.

## Container

Normally, we don't want our text to stick to the left border of the page; instead, we prefer to give it a bit of a margin. To ensure aesthetic appeal, the size of this margin should vary for different screen sizes. This important consideration is expressed in Bootstrap as follows:

```html
<div class="container"></div>
```

Naturally, I am oversimplifying things, and there is more to the 'container' than this, but for now on, here is the rule: Inside every section, there should be a container.

## 12 column grid

Often, the content we want to place inside the container doesn't span the full width. For example, we might have an image on the left side and some text on the right side. This is where the grid system comes into play.

It consists of 12 columns because this allows for easy division of the full width into halves, thirds, quarters, and combinations like 3/4 and 1/4 without referring to ratios.

In any case, simple two column grid looks like this:

```html
<div class="row">
    <div class="col-6">
        Left
    </div>
    <div class="col-6">
        Right
    </div>
<div>
```

Bootstrap is designed to accommodate different screen sizes, and for many classes, there is a way to specify the screen size to which the feature applies. If you want your content to be placed in two columns on medium or larger screens, you can use 'col-md-6'. In this case, on devices with smaller screens, the columns will stack vertically, one below the other.

The concept of columns in Bootstrap is so integral that even when defining full-width content, it is often described as a single-column cell spanning the full width.

## Centered content and offsets

When you want centered content that occupies a certain percentage of the full width, it's achieved using a column with an offset. Imagine you have 12 vertical bands, and you want to place something in the middle of your section that is approximately half wide.

You say

```html
<div class="row">
     <div class="col-6 offset-3">
         Centered content
     </div>
<div>
```

Essentially, 3 left vertical bands are left empty, then comes your column, which is 6/12 or 1/2 of the width. Then, two more bands are left empty, although this is not described explicitly.

Again, you can decide that on smaller screens the offset should be smaller or even disappear completely. This is achieved using appropriate size modifiers, such as 'offset-md-2' and similar.

## Footer

The footer is a special kind of section that is placed at the very bottom of your page. There is a special HTML tag for it, <footer>, similar to the <header> tag used for headers.

## Final page structure

So, this is what the outline of a <body> element on a typical Bootstrap HTML page looks like:

```html
<body>

    <!-- Navigation bar -->
    <nav class="...">
        <div class="container">...</div>
    </nav>

    <!-- Header -->
    <header class="...">
        <div class="container">...</div>
    </header>

    <!-- Multiple sections -->
    <section class="product-features my-3">
        <div class="container">
            <div class="row">
                <div class="col-6">
                    Left
                </div>
                <div class="col-6">
                    Right
                </div>
            <div>
        </div>

    ... repeat

    <!-- Footer -->
    <footer class="...">
        <div class="container">...</div>
    </footer>

</body>
```

There are libraries that describe GUI interfaces declaratively, for example, through XML. You have two options: either build your interface by directly creating GUI objects like Frames, Textboxes, etc., or create them from an XML description. In the latter case, a Window (or Page) object with the appropriate widgets and GUI controls will be created.

So, in this case, the Bootstrap framework is a tool used to declaratively describe a typical HTML page and its common elements. It is the browser that renders this description and creates the actual GUI objects.

## What are the alternatives?

Many people advocate for writing everything from scratch. While CSS has greatly improved since the time when tables were used for layout, and now we have CSS Flexbox and CSS Grid layouts, there is still much more complexity than it appears.

For example, Bootstrap uses different fonts for headers on devices with various screen sizes. Building a responsive dropdown menu would be an especially daunting task on its own. Yes, it is possible, but would it be better than the regular Bootstrap menu?

When I looked into the code of Bootstrap pages, I always thought they were too verbose with all these lengthy "mt-3 mb-2 py-md-1 offset-lg-4" class names. Not to the extent of Tailwind CSS's verbosity, but still, from my perfectionist perspective, HTML sections should only contain the class name, with the rest of the styling defined via CSS.

Now, I'm not so sure. I am ready for compromises. I am even okay with creating columns with single full-width cells, as long as it provides consistency and helps me understand the myriad examples of Bootstrap template code out there.