A brief chat about how to make a professional header with CSS (Headers)

56f50146681e723f53a2552b464e48d1.jpeg

An attractive web page header is essential to making a good first impression on your visitors. A well-designed header not only grabs attention, but also sets the tone for the entire site. Creating modern and visually appealing web page headers is easier than ever with CSS.

In this article, we'll explore some basic tips and hints to help you create stunning header layouts with CSS. We don't focus too much on the design, but on creating the layout and understanding the difficulties you might face while creating it.

Space-Between cannot be centered in a three-column header

First, let's talk about the three-column header, since that's the one I see most often implemented wrong.

Markup is relatively simple:

<header>
  <nav>
    <a href="/">ABC</a>

    <div>
      <a href="#">Features</a>
      <a href="#">Pricing</a>
      <a href="#">About us</a>
    </div>

    <div>
      <a href="#">Login</a>
    </div>
  </nav>
</header>


I put all the links in the navigation tags in the header. So it's a very simple markup. Normally, navigation should be center-aligned between the first and last item.

630f02b6c357298d4cf9dda4e6c7e380.jpeg

According to my observation, this problem has become a new problem in the front-end community, similar to the problem of "centering a div". Because many developers will use the space-between value of the justify-content attribute to solve this problem, but it does not actually center the middle element. Here's the same nav markup using the space-between value of the justify-content attribute, for comparison:

de4448d310d01421c22ee57e5de7e563.jpeg

The reason for this effect is that the left side is wider than the right side. Our middle element is center-aligned between the left and right elements, but in the context of the page, the middle element isn't really centered.

This is the first challenge when creating a header: getting the basic layout right. Don't try to add more until you've figured out what layout you want to achieve and how.

Before we move on, I spent a few hours on ProductHunt looking for and evaluating the three-column header. Most of them use the trick I showed of setting the justify-content property to space-between (thus, their navigation isn't really centered). Some people try to get around this problem (for example, by adding margins), while others give up with absolute positioning. Of course, these "hacks" can "solve" the problem, but they add complexity. Your headers will become unmaintainable and you will have a bad feeling when you go back to them again. Having said that, this "real solution" is also somewhat tricky.

Here's how to do it:

header > nav {
  display: flex;
}

header > nav > * {
  display: flex;
}

header > nav > :first-child,
header > nav > :last-child {
  flex: 1 1 0;
}

header > nav > :last-child {
  justify-content: flex-end;
}

Results as shown below:

733c3cc30e87eab1a0ab606de7e847d8.png

Let's talk about this solution.

First, the selectors I'm using are too specific. This is done to make nesting relationships clearer.

Then, each element under the header is a flex container. This is also unnecessary. Currently it is only used on the last child of the nav to move its child to the right.

That leaves just this rule: flex: 1 1 0; which is our main concern here. I apply this rule to the first and last element. It allows them to grow and shrink, and sets their base size to 0 pixels. That's what this whole "hack" is all about. Since we set their base size to 0, they will grow proportionally, thus centering our middle element.

196705a8afd0096068df58d944e6c6a5.jpeg

When creating the header layout, of course, centering the middle elements of the header wasn't the only challenge we faced.

Hide the navigation bar on smaller screens

Like using the space-between value of the justify-content property, the above pattern allows us to hide the intermediate navigation while keeping the layout intact. When we hide the middle element, the effect is as follows:

037d1ca2540ff237427c6590277b49b6.jpeg

Of course, it's trivial to replace the login with a button. So, let's talk about something else.

Suppose our header looks like this:

0090c5cc5a87ad634d998ab2be6edac1.jpeg

<header>
  <nav>
    <a href="/">ABC Company</a>

    <div class="desktop-navigation">
      <a href="#">Features</a>
      <a href="#">Pricing</a>
      <a href="#">About us</a>
      <a href="#">Terms of Service</a>
    </div>

    <div class="action-navigation">
      <input type="search" aria-label="search" />
      <a href="#">Sign Up</a>
      <a href="#">Login</a>
    </div>
  </nav>
</header>

Now, when our viewport gets smaller, we have a problem with our header:

3f9845fae57f4541850d5f4719bc68e6.jpeg

We can add a media query for this, where we replace certain elements with icons, or simply hide the search. But modern CSS also allows for a different solution.

For example, we can create a container query. Here is an updated code sample:

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

a {
  color: #000;
  text-decoration: none;
}

header {
  padding: 1.5rem;
}

header > nav {
  display: flex;
}

header > nav > * {
  display: flex;
}

header > nav > :first-child,
header > nav > :last-child {
  flex: 1 1 0;
}

header > nav > :last-child {
  justify-content: flex-end;
}

header > nav > :last-child,
.desktop-navigation {
  gap: 1.5rem;
}

.action-navigation {
      container-type: inline-size;
      container-name: action-navigation;
    }

@container action-navigation (max-width: 400px) {
      input {
        display: none;
      }
    }

I just added these lines:

.action-navigation {
  container-type: inline-size;
  container-name: action-navigation;
}

@container action-navigation (max-width: 400px) {
  input {
    display: none;
  }
}

Of course, you might argue that you can do this with media queries as well. Nothing special. But the advantage of container queries is that we can specify a minimum width for the container. We don't care how big the viewport is, but we do know: if our container width is less than 400px, it will get really ugly. This is one of those features that I'm really looking forward to being widely supported.

Sticky Top Navigation Bar

I still see some using position: fixed to implement the top navigation bar, even though sticky is a better solution.

Why is sticky better? Consider the following code:

<style>
  * {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
  }

  a {
    color: #000;
    text-decoration: none;
  }

  header {
    padding: 1.5rem;
    width: 100%;
    position: fixed;
  }

  header > nav {
    display: flex;
  }

  header > nav > * {
    display: flex;
  }

  header > nav > :first-child,
  header > nav > :last-child {
    flex: 1 1 0;
  }

  header > nav > :last-child {
    justify-content: flex-end;
  }

  .desktop-navigation {
    gap: 1.5rem;
  }
</style>

<header>
  <nav>
    <a href="/">ABC Company</a>

    <div class="desktop-navigation">
      <a href="#">Features</a>
      <a href="#">Pricing</a>
      <a href="#">About us</a>
    </div>

    <div class="action-navigation">
      <a href="#">Login</a>
    </div>
  </nav>
</header>

<main>
  Some content
</main>

In this case the header has position: fixed. As a result, the main content area moves to the top of the site because no space is reserved in the document for the header. It is out of flow.

9a1c0fb16497b46f98ce0c6d6fe033b1.png

In this case, the workaround is to use margin-top to offset the main content area, moving it below the header. You'll likely see this workaround a lot, even on newer sites. The problem is that the sticky property doesn't always exist. It is a relatively new property. That's why you can still find some tutorials using position: fixed instead of sticky. But with sticky, we don't need margin-top offset. The header element still takes up space as if it were in the document.

Here is an updated code example with position: sticky :

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

a {
  color: #000;
  text-decoration: none;
}

header {
  padding: 1.5rem;
  position: sticky;
  top: 0;
}

header > nav {
  display: flex;
}

header > nav > * {
  display: flex;
}

header > nav > :first-child,
header > nav > :last-child {
  flex: 1 1 0;
}

header > nav > :last-child {
  justify-content: flex-end;
}

.desktop-navigation {
  gap: 1.5rem;
}

As you can see, this approach is much simpler. We don't need to set arbitrary offsets for the content.

That's it, friends! Thank you so much for reading!

Finish

Do you know of any other common mistakes about header layouts? Or are you aware of other challenging elements? I'd love to learn more in the comments!

Due to the limited space of the article, today’s content will be shared here. At the end of the article, I would like to remind you that the creation of the article is not easy. If you like my sharing, please don’t forget to like and forward it, so that more people in need See. At the same time, if you want to gain more knowledge of front-end technology, welcome to follow me, your support will be the biggest motivation for me to share. I will continue to output more content, so stay tuned.

Guess you like

Origin blog.csdn.net/Ed7zgeE9X/article/details/131671616