Let's build a layout from scratch
Tags: html, css, webdev, ui
Published: 2021-02-05 15:21:18

Today let's build the layout for an entire website from scratch using HTML, CSS, flexbox, grid layout and so much more...

Read the full article or watch me code this on Youtube:

{% youtube Hc48OFEemHs %}

# Result

https://github.com/crayon-code/website-cloud-service

![screenshot](https://dev-to-uploads.s3.amazonaws.com/i/81m1h33rp7d4oofstlin.png) 

## Blank HTML5 Document

Let's start with a blank HTML5 Document. This is our starting point which we're going to extend bit by bit throughout the following chapters.

> Did you know that typing an exclamation mark (!) and hitting tab in VS CODE generates a blank HTML5 Document?

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BEAMCLOUD</title>
  </head>
  <body>
    <!-- content will go here -->
  </body>
</html>
```

## Using Styles and External Fonts

There are three (more or less) external resources we have to include in the documents `<head>`:

1. Our own stylesheet in `styles.css`.
1. We'll be using the font _Nunito_ as the page's default font. Therefore it is loaded via Google Fonts. The font weights 200, 400 and 700 will be used. Especially 200 looks quite elegant with larger text (as in headings).
1. Font Awesome via `cdnjs.com`. Watch out for the `integrity` attribute as it is a nice security feature. If the SHA checksum of the file downloaded by the user agent differs from the SHA checksum given in the `integrity` attribute, the browser knows that the downloaded content was tampered with and is therefore rejected. See [this MDN Article](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) for more about _subresource integrity_.

```html
<head>
  ....

  <!-- or own styles -->
  <link rel="stylesheet" 
    href="styles.css"
    type="text/css" />

  <!-- "Nunito" font via google fonts -->
  <link rel="preconnect" 
    href="https://fonts.gstatic.com" />
  <link rel="stylesheet"
    href="https://fonts.googleapis.com/css2?family=Nunito:wght@200;400;700&display=swap" >

  <!-- Font Awesome via CDNJS  -->
  <link rel="stylesheet" 
    href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" 
    integrity="sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w==" 
    crossorigin="anonymous" />
  </head>
```

## Variables and Basic Styles

Now, in our `styles.css` file, let's start with a few basic things. For instance, _variables_. It's extremely useful for customization to have the colors we'll be using in variables and common, repetitive things like the transition setup also.

```css
:root {
  --bg-start: #2c35a2;
  --bg-end: #0f133b;

  --highlight-fg: #161c49;
  --highlight-primary: #73fff5;
  --highlight-secondary: #cf0389;

  --fg-color: rgba(255, 255, 255, 0.9);
  
  --transition: 250ms ease-out;
}
```

This block resets `padding`, `margin` and `box-sizing` for each element, so it brings us a great deal of consistency across browsers and elements.

```css
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
```

On the root `<html>` element we're defining the basic text color as well as the basic font, including the font size. This is quite important, as we're going to use a lot of `rem` values and they are always relative to the font size being set on the root `<html>` element.

```css
html {
  color: var(--fg-color);

  font-family: "Nunito", sans-serif;
  font-weight: 400;
  font-size: 18px;
}
```

The `<body>` is simply going to be a flex container that centers content horizontally and puts content to the very top. `min-height: 100vh` ensures that the body always takes at least the full viewport height, which spans the gradient across the entire page.

```css
body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;

  padding: 2rem;
  min-height: 100vh;


  background: linear-gradient(
    45deg,
    var(--bg-start), 
    var(--bg-end)
  );
}
```

## Logo

The first actual content element is the logo. It's embedded in a `header` tag and is simply a `div` with an `img` tag referencing an SVG image and a logo text.

```html
<body>
  <header>
    <div class="logo">
      <img src="logo.svg">
      beamcloud
    </div>
  </header>
</body>
```

Styling on this one is quite simple, as it is also a flex container that puts the image and the logo text next to each other and centers them vertically. Additionally the height of the image is set to match the font size.

```css
.logo {
  display: flex;
  align-items: center;

  text-transform: uppercase;
  font-size: 2rem;
}

.logo > img {
  height: 2rem;
  margin-right: 1rem;
}
```

## Navigation Bar

The navigation bar is the second element inside the header and uses an unordered list `ul` for the navigation items embedded in a `nav` providing semantics already on the markup level.


```html
<body>
  <header>
    ...
    <nav>
      <ul>
        <li class="active">
          <a href="#">About Us</a>
        </li>
        <li>
          <a href="#">Reviews</a>
        </li>
        <li>
          <a href="#">Pricing</a>
        </li>
        <li class="highlight">
          <a href="#">Sign In</a>
        </li>
      </ul>
    </nav>
  </header>
</body>
```

In order to arrange logo and navigation items next to each other, the `header` element is also set to be a flex-container and pushing both items to the very left/right by using `justify-content: space-between.`

```css
header {
  display: flex;

  justify-content: space-between;
}
```

Since (almost?) every browser renders links in a highlighted color and underlined, let's undo that kind of styling by setting the color to the respective variable and unsetting all kinds of text decoration.

```css
a {
  color: var(--fg-color);

  text-decoration: none;
}
```

Finally, for the navigation items themselves we're using a grid layout being configured for automatically flowing all items each into their own column. By using `grid-auto-columns: max-content` each cell is wrapped nicely around a navigation item without making the contained text wrap.

```css
nav > ul {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: max-content;
  gap: 0.5rem;

  list-style-type: none;
}

nav > ul a {
  padding: 0.25rem 1.25rem;

  text-transform: uppercase;

  transition: color var(--transition),
    background-color var(--transition);
}
```

## Main Content

For the main content of the page we're also using the `main` semantic HTML tag. Inside it is a section tag containing a heading and a paragraph and a nice little artwork which we're going to put next to it.

```html
<body>
  ...
  <main>
    <section>
      <div class="content">
        <h1>Scale well, sleep well.</h1>
        <p>
          Get the most out of your apps and websites with our highly available and scalable cloud infrastructure. All you need, directly at your fingertips.
        </p>
        <a href="#" class="button">
          Learn More
        </a>
      </div>
      <div class="artwork">
        <img src="artwork.svg" >
      </div>
    </section>
  </main>
</body>
```

The `section` itself is also going to be a grid layout, but this time it is explicitly configured to have exactly two columns, whereas the left column is given one fraction (`1fr`) of the available space and the right column two fractions (`2fr`).

```css
main {
  max-width: 50rem;
  padding: 2rem;
}

section {
  display: grid;
  grid-template-columns: 1fr 2fr;
  grid-template-rows: 1fr;
  grid-template-areas: "content artwork";
  place-content: center;
}

section > .content {
  grid-area: content;
  place-self: center stretch;
}

section > .artwork {
  grid-area: artwork;
  place-self: stretch;
}

h1 {
  margin-bottom: 1rem;

  color: var(--highlight-primary);

  font-size: 2.5rem;
  font-weight: 200;
}

p {
  margin-bottom: 1rem;

  font-size: 1.25rem;
  font-weight: 200;
}
```

## Footer

At last, we have reached the bottom of the page being a `footer`. We'll be using it to put a bunch of social media icons which is why we have included font awesome at the very beginning.

```html
<body>
  ...
  <footer>
    <a href="#"><i class="fab fa-twitter"></i></a>
    <a href="#"><i class="fab fa-facebook-f"></i></a>
    <a href="#"><i class="fab fa-instagram"></i></a>
    <a href="#"><i class="fab fa-youtube"></i></a>
    <a href="#"><i class="fab fa-github"></i></a>
    <a href="#"><i class="fab fa-linkedin-in"></i></a>
  </footer>
</body>
```

The footer is again a grid layout configured to automatically flow each element into its own column with a gap of `1rem` between each of them.

```css
footer {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min-content;
  gap: 1rem;
  justify-content: center;

  margin-top: 4rem;
  padding-top: 1rem;
  width: 80%;
}
```

To spice the header slightly up we're not going to use a "normal" border, but a gradient. Therefore the `footer::before` pseudo-class allows us to put an element at the top of the footer having a gradient as background. And that's already it!

```css
footer {
  position: relative;
  ...
}

footer::before {
  content: '';

  position: absolute;
  top: 0%;
  left: 0%;
  right: 0%;
  height: 2px;

  background: linear-gradient(
    90deg,
    transparent,
    var(--highlight-secondary),
    transparent
  );
}
```