> For the complete documentation index, see [llms.txt](https://reyvaleza.gitbook.io/vibe.d-tutorial/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://reyvaleza.gitbook.io/vibe.d-tutorial/a-fixed-navbar-and-sticky-footer.md).

# A fixed navbar and sticky footer

It is nice to work with Bootstrap. CSS seems less intimidating and more approachable, and they also keep improving Bootstrap every year. However, there are developments in standard CSS which we tend to ignore because of the familiarity and convenience of Bootstrap. And some dev outfits might not want its developers to use Bootstrap, so it’s always good practice to learn alternatives.

Let’s create a new project with a fixed navbar and a sticky footer using only CSS Grid.

On the command window, create a new project named **no\_bs**.

Stop the server if it is still running with Ctrl-C.

```
^CReceived signal 2. Shutting down.
Stopped to listen for HTTP requests on ::1:8080
Stopped to listen for HTTP requests on 127.0.0.1:8080
```

And create the **no\_bs** project.

c:\vibeprojects\hello>**cd ..**\
c:\vibeprojects>**dub init no\_bs -t vibe.d**

```
Select a package recipe format:
1) sdl    2) json   
#? [2]: 
Name [no_bs]: 
Description [A simple vibe.d server application.]: 
Author name [rey]: 
Select or enter an SPDX license-identifier (https://spdx.org/licenses/):
 1) BSL-1.0 (Boost)               8) BSD-                         
 2) MIT                           9) MPL- (Mozilla)               
 3) Unlicense (public domain)    10) EUPL-                        
 4) Apache-                      11) CC- (Creative Commons)       
 5) AGPL-                        12) Zlib                         
 6) GPL-                         13) ISC                          
 7) LGPL-                        14) proprietary                  
? [14]: 
Copyright string [Copyright © 2026, rey]: 
Add dependency (leave empty to skip) []: 
     Success created empty project in /vibeprojects/no_bs
             Package successfully created in no_bs
```

Then enter the **no\_bs** directory:

c:\vibeprojects>**cd no\_bs**\
c:\vibeprojects\no\_bs>

Open the **no\_bs** folder in VS Code and edit **source\app.d** to make it look like this:

```d
import vibe.vibe;

void main()
{
  auto settings = new HTTPServerSettings;
  settings.port = 8080;
  settings.bindAddresses = ["::1", "127.0.0.1"];
  auto router = new URLRouter;
  router.get("*", serveStaticFiles("public/"));
  router.get("/", staticTemplate!"index.dt");
  router.get("/about", staticTemplate!"about.dt");
  router.get("/contact", staticTemplate!"contact.dt");
  router.get("/login", staticTemplate!"login.dt");
  auto listener = listenHTTP(settings, router);
  scope (exit) listener.stopListening();
  runApplication();
}
```

Next, create **views\layout.dt:**

```jade
doctype 5
html
  head
    title Employee Timekeeping System
    include styles.dt
  body
    div.container
      div.menu
        include menu.dt
      div.content
        block maincontent
      div.footer
        include footer.dt
```

Then create **views\styles.dt**:

```css
:css
  body
  {
    margin: 0;
    padding: 0;
  }
  .container
  {
    display: grid;
    grid-template-rows: 40px auto 30px;
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
  }
  .menu
  {
    position: fixed;
    top: 0;
    width: 100%;
    padding: 10px 0;
    background-color: whitesmoke;
  }
  .menu-item
  {
    display: inline;
  }
  .item-link
  {
    margin-left: 30px;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    font-size: 18px;
    color: teal;
    text-decoration: none;
  }
  .item-link-right
  {
    float: right;
    margin-right: 30px;
  }
  .modal-form
  {
    position: fixed;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0,0,0,0.5);
    z-index: 99999;
    opacity: 0;
    pointer-events: none;
  }
  #login:target, #find_employee:target
  {
    opacity: 1;
    pointer-events: auto;
  }
  .modal-form-grid
  {
    display: grid;
    grid-template: 30px 30px 30px / 1fr 1fr;
    grid-gap: 10px;
  }
  .text-control
  {
    grid-column: 1 / 3;
  }
  #but-reset
  {
    grid-column: 1 / 2;
  }
  #but-submit
  {
    grid-column: 2 / 3;
  }
  .modal-form-wrapper-login
  {
    width: 250px;
    position: absolute;
    right: 0;
    margin-top: 40px;
    padding: 25px 20px;
    border-radius: 10px;
    text-align: center;
    background-color: whitesmoke;
  }
  .modal-form-wrapper-find_employee
  {
    width: 250px;
    position: relative;
    left: 280px;
    margin-top: 40px;
    padding: 25px 20px;
    border-radius: 10px;
    text-align: center;
    background-color: whitesmoke;
  }
  .content
  {
    padding: 40px 30px;
  }
  .footer
  {
    position: fixed;
    bottom: 0;
    width: 100%;    
    background-color: whitesmoke;
    padding: 5px 0;
  }
  .copyright
  {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    font-size: 14px;
    text-align: center;
    color: teal;
  }
  .form-hidden
  {
    padding: 0;
    margin: 0;
    display: inline;
  }
```

Then create **views\menu.dt**:

```jade
div.menu-item
  a.item-link(href="/") Home
div.menu-item
  a.item-link(href="about") About us
div.menu-item
  a.item-link(href="contact") Contact us
div.menu-item
  a.item-link.item-link-right(href="login") Login
```

Then create **views\index.dt**:

```jade
extends layout
block maincontent
  h2 The Lorem Ipsum Company
  div.
    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    Nam nec urna arcu. Quisque eleifend posuere vestibulum.
    In sed magna mauris. Phasellus bibendum ligula et placerat
    vulputate. In non suscipit lectus, a laoreet odio. Donec
    at sapien eu nisi porta condimentum. Morbi non varius ex,
    nec luctus nisl. Aenean varius dui quis arcu auctor luctus.
    Integer efficitur ornare massa, ac suscipit enim sagittis et.
    Proin vestibulum tellus in ipsum ultrices, sed imperdiet
    sapien euismod. Praesent vel facilisis mauris. Proin finibus
    congue tellus, non varius ante. Nullam tincidunt dolor felis.
    Pellentesque non luctus tellus. Curabitur et sapien at justo
    fringilla feugiat et a erat.
    <br /><br />
```

And make stub pages for **views\about.dt**:

```jade
extends layout
block maincontent
  h2 The About Us page
  div
    <h3>This is the About Us page.</h3>
```

and **views\contact.dt**:

```jade
extends layout
block maincontent
  h2 The Contact Us page
  div
    <h3>This is the Contact Us page.</h3>
```

and **views\login.dt:**

```jade
extends layout
block maincontent
  h2 The Login page
  div
    <h3>This is the Login page.</h3>
```

After you compile and run, you should be able to see these pages:

<figure><img src="/files/0e80DpBqfCEeYseNTvxu" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/d1tay8opaBRBgGw6QQSC" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ybmMgTvaQQiDQ2M8EUPg" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Fo0DivSr8SLv8Gw0ueX9" alt=""><figcaption></figcaption></figure>

We just created a layout with a fixed navbar and a sticky footer without using Bootstrap. If you expand and contract the browser, you will see that the middle row expands and contracts to fit the page, making the pages responsive.

In the **views\styles.dt** file, we declared this:

```css
  .container
  {
    display: grid;
    grid-template-rows: 40px auto 30px;
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
  }
```

We did not declare any columns, effectively making the whole page just one column with three rows. The menu bar is on the top row and the footer is on the bottom row, with the middle row expanding and contracting to fit the page height when the browser is resized, thus making it responsive.

With CSS Grid, you will notice that the layout terms are declared in the CSS file so the HTML file is cleaner compared to using Bootstrap.&#x20;

For a good overview of CSS Grid, I recommend this site:&#x20;

{% embed url="<https://www.freecodecamp.org/news/learn-css-grid-in-5-minutes-f582e87b1228/>" %}

Now let's add a modal dialogue to the menu without JavaScript.
