4

Given a logical (search engine readable) HTML menu containing an unordered list menu wrapped inside a <nav>, starting with item Home and ending with item Blog. I have tried several things in pure CSS and HTML but cannot achieve what I want.

https://jsfiddle.net/6zt3gfp4/

What I would like, is this:

  1. Align the whole vertical menu to the top left edge of the screen, automatically.
    Regardless of the number of and/or length of the list items contained in the <nav>!!

  2. Expand the clickable area of each underlined link to its entire blue block.
    For ease of use when hovering and clicking a menu item.

  3. Ideally we should leave my broken start behind and opt for a FlexBox CSS design.
    Perhaps that gives us all better flexibility for achievng this. That would be a bonus!

enter image description here

nav {
  text-align:center;
  transform: rotate(-90deg) translateX(-240px) translateY(-100px);
  margin: 0;
  top: 0px;
  left: 0px;
  position: absolute;
}

nav li{
    display: inline-block;
    background-color: blue;
    height: 24px;
    line-height: 24px;
    vertical-align: middle;
    margin: 5px auto;
    padding: 1em;
}

nav li a{
  color: #fff;
}

nav li a:hover{
  background: black;
}

nav li.selected {
  background-color: purple;
}
<nav>
  <ul>
    <li><a href="#">Home</a></li>
    <li class="selected"><a href="#">Philosophy</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Products</a></li>
    <li><a href="#">Contact</a></li>
    <li><a href="#">Blog</a></li>
  </ul>
</nav>
Sam
  • 15,254
  • 25
  • 90
  • 145

1 Answers1

4

Don't play a lot with transformation. Use writing-mode then move the style applied to li to a to make the link area bigger.

nav {
  top: 0px;
  left: 0px;
  position: absolute;
}
nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
nav li {
  background-color: blue;
  writing-mode: vertical-rl; /* */
  transform: scale(-1); /* */
  margin: 5px 0;
}
nav li a {
  color: #fff;
  padding: 1em;
  display: inline-block;
  line-height: 24px;
}
nav li a:hover {
  background: black;
}
nav li.selected {
  background-color: purple;
}
<nav>
  <ul>
    <li><a href="#">Home</a></li>
    <li class="selected"><a href="#">Philosophy</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">Products</a></li>
    <li><a href="#">Contact</a></li>
    <li><a href="#">Blog</a></li>
  </ul>
</nav>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 1
    This doesn't seem to work properly in Firefox - don't know why. What seems to work in both Chrome and Firefox is to move writing-mode to the ul element and set the flex direction to row. – Alohci May 23 '22 at 09:23
  • 1
    @Alohci oops didn't check FF. It's seems that removing display:flex also fixes the issue. Not need at end since the default flow could do the job – Temani Afif May 23 '22 at 09:29
  • Wonderfully Elegant! Thank you! Answer accepted. Just a strange thing: in both your original and updated version there seems to be a pesky extra pixel of margin between the two last items! I can't get rid of it when setting the margin to 0. A thin white line can be observed between Blog and Contact in Chrome. Strange?! In Firefox the new version works perfectly! See old https://jsfiddle.net/dep0t3sv/3/ and new https://jsfiddle.net/vhm2Lno6/1/ – Sam May 23 '22 at 10:26
  • Even when adding `margin: -1px 0; border-top: 2px solid white;` to `nav li`, in Chrome the space between the last two blocks is slightly larger... Strange. Am I the first person ever to have noticed this? I'm not sure therefore I wonder if I will be the _last_ person ever to notice this imperfection lol. – Sam May 23 '22 at 10:31
  • @Såm probably a sub pixel rendering issue. Unfortunately, we cannot control this. Either consider negative margin or add some box-shadow to cover that space. – Temani Afif May 23 '22 at 10:34
  • Awesome idea, didn't think of that (box shadow of 1px with blur set to 0px), thanks! – Sam May 23 '22 at 11:51