HTML/CSS question

Soen Eber

Vatican mole
VVO Supporter 🍦🎈👾❤
Joined
Sep 20, 2018
Messages
320
I've created both a horizontal menu and a vertical menu for my student final project (we can create anything we want. so long as we meet a minimal list of requirements so this isn't a "cheating" question). The HTML & CSS are very close for both.

I know conditional logic is very limited, and I don't want to use JavaScript because I want the website to work without needing it. I also don't want to use an "empty" conditional hack because it goes against the core purpose of "empty" to identify unfilled fields, so would be confusing to whoever has to read it (such as a tired and grouchy instructor at the end of the semester at 11 PM who has run out of coffee). What's the best way to merge the CSS so it can be used for both?

Here's what I have for the original toolbar:
Code:
html
    <nav>
        <h2>Navigation Menu</h2>
        <ul class="nav">
          <li><a href="final.html">Home</a></li>
          <li><a class="selected" href="boilerplate.html">Boilerplate</a></li>
          <li><a href="#contact">Contact</a></li>
          <li><a href="#about">About</a></li>
        </ul>
    </nav>
 
css
    :root {
      --body-bg-color: beige;
      --nav-fg-color: #ffffff;
      --nav-bg-color: #3333ff;
      --nav-bg-selected-color: #000088;
      --nav-bg-hover-color: #8888ff;

    ul.nav {
      list-style-type: none;
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: var(--nav-bg-color);
    }
    ul.nav li {
      float: left;
    }
    ul.nav li a {
      display: block;
      color: var(--nav-fg-color);
      text-align: center;
      padding: 16px;
      text-decoration: none;
    }
    ul.nav li a.selected {
      display: block;
      background-color: var(--nav-bg-selected-color);
      text-align: center;
      padding: 16px;
      text-decoration: none;
    }
    ul.nav li a:hover {
      background-color: var(--nav-bg-hover-color);
    }
For the vertical navigation, I've copied the css, changing ul.nav to ul.nav.v, and changed:
Code:
ul.nav-v li {
    width: 100px;
/*  float: left;*/
}
and I've added a width to the ul.nav-v selector. I suspect I should use attribute selectors but my brain is kinda fogged right now, and this is only a "nice to have" for the project. Also, ignore that I'm using pixel measurements, I'll properly change them to percents once I start working on the responsive requirement.

Thanks!
 

Beebo Brink

Resident Grouch
Joined
Sep 20, 2018
Messages
849
I've read this over a few times, so forgive me if I'm just missing the answer in what you've posted. Under what circumstances would you use one menu over the other? Or do you want to use both at the same time? I'm confused.

At first I assume one would be the default display and the other a mobile display, but then you mention doing responsiveness later. So apparently this is not about responsiveness?
 
  • 1Thanks
Reactions: Soen Eber

Soen Eber

Vatican mole
VVO Supporter 🍦🎈👾❤
Joined
Sep 20, 2018
Messages
320
Actually it would be the responsive display, but currently I'm trying to build up a series of copy/paste boilerplate I can store on a snippets page. Since the html and css share common elements, I was wondering how I could combine both menus, triggering one or the other with ... something, probably a css variable or at worst, code which can be commented/uncommented.

Here's the vertical bar code: The only differences are this is called nav-v, and what I pointed out above in the <nav-v and nav-v.li classes with the width and float tags.
Code:
            <nav>
                <ul class="nav-v">
                  <li><a href="final.html">Home</a></li>
                  <li><a href="boilerplate.html">Boilerplate</a></li>
                  <li><a class="selected" href="work.html">Work</a></li>
                  <li><a href="final.html#contact">Contact</a></li>
                  <li><a href="#about">About</a></li>
                </ul>
            </nav>

ul.nav-v {
  list-style-type: none;
  width: 100px;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: var(--nav-bg-color);
}
ul.nav-v li {
    width: 100px;
/*  float: left;*/
}
ul.nav-v li a {
  display: block;
  color: var(--nav-fg-color);
  text-align: center;
  padding: 16px;
  text-decoration: none;
}
ul.nav-v li a.selected {
  display: block;
  background-color: var(--nav-bg-selected-color);
  text-align: center;
  padding: 16px;
  text-decoration: none;
}
ul.nav-v li a:hover {
  background-color: var(--nav-bg-hover-color);
}
 
Last edited:

Beebo Brink

Resident Grouch
Joined
Sep 20, 2018
Messages
849
If the point is to style the menu differently for mobile versus desktop, then you should only have ONE HTML menu with your CSS classes identifying the menu, not the way in which you intend to style it.

To expand on that, classes should always be agnostic as to the details of display. No "nav-v" or "nav-h" because those are referencing your style choices, rather than the menu purpose. If you did use two menus -- which you shouldn't need -- use class names such as "nav-desktop" and "nav-mobile." Those describe the context and purpose of the element, rather than the more ephemeral styling itself.

So back to your responsive modes. To control the display of your menu, you start with a default display, then use media queries to define the alternate context. If your default is desktop, then use your old nav-h in your style sheet, THEN set up a media query for the styles that you defined as nav-v.

For example, you decide that for any screen width smaller than 480px, you want your vertical styling:
@media screen and (max-width: 480px) {

/* insert all styles for menu display on mobile */
ul.nav li { width: 100px; /* float: left;*/ }

}

The current approach however, is "mobile first." As in start with a block of styles that assume a mobile display, then add styles to change that look if the screen width gets larger. After years of "desktop first" I have a very difficult time working with this approach, but if you're just starting out, it's probably the way you should approach your style building.

With mobile first, you would work with min-width rather than max-width. In this case, any screen width greater than 740px will trigger the new block of styles to overwrite the ones above it in the style sheet.

@media screen and (min-width: 740px) {

/* insert all styles for menu display on desktop*/

}
 
  • 1Thanks
Reactions: Soen Eber

Beebo Brink

Resident Grouch
Joined
Sep 20, 2018
Messages
849
But wait, there's more!!

The media queries in my post above were based on standard breakpoints for desktop to tablet to large mobile, etc. etc. There are tables of these breakpoints that can be used for reference, but as devices proliferate, these breakpoints are getting unwieldy to accommodate. As a result, there's yet another approach that avoids the standard device-width breakpoints in favor of a more nuanced fluid design. I'm not sure I can really do that approach justice, but let me give it a shot.

So this is your menu of relatively short items that stack for better display on mobile:
Home
Boilerplate
Work
Contact
About


Rather than use device screen width values to decide when to shift the display from vertical to horizontal, you evaluate the element itself to determine when you want to change over to horizontal.

So let's say that on average, each menu item is only about 25px and maybe looks okay up to about 75px in width. Beyond 75px each item line is starting to pick up so much blank space that the menu looks weird. Based on that, you calculate that 250px is enough room to display a horizontal menu. If there is more than 250px of screen width available, regardless of device, you want a horizontal display.

You set up a media query specifically for your nav menu:

@media screen and (min-width: 250px) {

/* insert all styles for nav horizontal display */

}

Home | Boilerplate | Work | Contact | About

Then you evaluate all other design elements and determine what is the breakpoint for that part of your layout and you create media queries for those element-specific breakpoint.

ETA: It's been awhile since I've worked closely with media queries and I easily get confused with min/max widths. So I've re-edited this post a few times, correcting errors. I can't vouch that this version (whenever you see it), is the correct one....
 
Last edited: