0

I have a single-line/row navigation/menu where some items have bigger font size but I want all items' text to be aligned with harmony, along the base line.

I also need the items to react to hover on the full height of the menu so user don't have to aim the smaller text (this is for sub-menu but not part of this question).

I tried with Flexbox but I can't mix align-items: stretch (full height) and align-items: baseline (text alignment)

Note: Text of menu items are in menu-item-label wrappers because I will add more stuff to the item (dropdown arrows, picto...) but it's the text alignment that counts.

body {
  font-size: 24px; /* Big value to ease highlighting of mis-alignemnt */
}

.some-existing-container {
  /* This container has some dimensions: I don't think it would cause conflict. */
  width: 100%;
  height: 4em;

  display: flex;
  align-items: center; /* Not mandatory */

  border: 1px solid blue; /* Highlighting */
}

.menu {
  display: flex;
  align-items: baseline;

  border: 1px solid green; /* Highlighting */
}

.menu-item {
  border: 1px dotted brown; /* Highlighting */
}

.menu-item:hover {
  background-color: grey; /* Highlighting */
}

.menu-item-label {
  border: 1px dotted pink; /* Highlighting */
}

.other {
  margin-left: auto; /* Places this block to the right in .some-existing-container */

  border: 1px solid purple; /* Highlighting */
}

.bigger {
  font-size: 4rem;
}

.stretched {
  align-items: stretch;
}
<p>Variant 1: Texts are aligned but items does not occupies the whole height:</p>
<div class="main">
  <div class="some-existing-container">
    <div class="menu">
      <div class="menu-item">
        <div class="menu-item-label">
          Home
        </div>
      </div>
      <div class="bigger menu-item">
        <div class="menu-item-label">
          Item1
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item2
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item3
        </div>
      </div>
    </div>
    <div class="other">
      Other
    </div>
  </div>
</div>
<p>Variant 2: Items of same-and-full height but texts are not aligned:</p>
<div class="main">
  <div class="some-existing-container">
    <div class="menu stretched">
      <div class="menu-item">
        <div class="menu-item-label">
          Home
        </div>
      </div>
      <div class="bigger menu-item">
        <div class="menu-item-label">
          Item1
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item2
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item3
        </div>
      </div>
    </div>
    <div class="other">
      Other
    </div>
  </div>
</div>

I would like to mix the two as the montage below:

Example of desired render

Is it even possible (with or without JavaScript)?

I have also tried with Grid layout without success (see this JSFiddle).

CDuv
  • 2,098
  • 3
  • 22
  • 28

4 Answers4

0

I would keep the baseline alignment and consider a pseudo elemen trick to increase the hoverable area:

body {
  font-size: 24px; /* Big value to ease highlighting of mis-alignemnt */
}

.some-existing-container {
  height: 4em;
  display: flex;
  align-items: center; 
  border: 1px solid blue; 
}

.menu {
  display: flex;
  align-items: baseline;
  border: 1px solid green; 
  overflow:hidden;
}

.menu-item {
  border: 1px dotted brown; 
  position:relative;
  z-index:0;
}
.menu-item::before {
  content:"";
  position:absolute;
  z-index:-1;
  top:-200px;
  bottom:-200px;
  left:0;
  right:0;
}

.menu-item:hover,
.menu-item:hover::before{
  background-color: grey;
}

.menu-item-label {
  border: 1px dotted pink; 
}

.other {
  margin-left: auto; 
  border: 1px solid purple; 
}

.bigger {
  font-size: 4rem;
}
<div class="main">
  <div class="some-existing-container">
    <div class="menu">
      <div class="menu-item">
        <div class="menu-item-label">
          Home
        </div>
      </div>
      <div class="bigger menu-item">
        <div class="menu-item-label">
          Item1
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item2
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item3
        </div>
      </div>
    </div>
    <div class="other">
      Other
    </div>
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thanks for the solution: it works great! But I have a feature in the menu I didn't imagined would be broken by this solution (so I did not put it in the original post, my bad): I have a sub-menu (a `
    • ...
    ` inside the `` blocks) that only appears, below the menu item when the latter is hovered. The `overflow: hidden;` on `.menu` makes it non-visible (see [example JSFiddle](https://jsfiddle.net/8610sqdz/)). Do you think there is a way for you solution to be made compatible with this "sub-menu feature"?
    – CDuv Mar 07 '21 at 01:16
  • Sorry: new JSFiddle with more actual hoped sub-menu representation: https://jsfiddle.net/069utjvd/ – CDuv Mar 07 '21 at 01:50
  • @CDuv sorry but I don't think this solution will work with sub meny. I suggest you to edit your question with that requirement (and remove the accepted answer) probably you will get more ideas. – Temani Afif Mar 07 '21 at 07:39
-1

This is the result when I fixed your css a bit.

body {
  font-size: 24px; /* Big value to ease highlighting of mis-alignemnt */
}

.some-existing-container {
  /* This container has some dimensions: I don't think it would cause conflict. */
  width: 100%;
  height: 4em;

  display: flex;
  align-items: center; /* Not mandatory */

  border: 1px solid blue; /* Highlighting */
}

.menu {
  display: flex;
  align-items: baseline;
  /* Add this css */
  height: 4rem;
  ///////////////
  border: 1px solid green; /* Highlighting */
}

.menu-item {
  border: 1px dotted brown; /* Highlighting */
  /* Add this css */
  display: flex;
  align-items: center;
  //////////////////
}

.menu-item:hover {
  background-color: grey; /* Highlighting */
}

.menu-item-label {
  border: 1px dotted pink; /* Highlighting */
}

.other {
  margin-left: auto; /* Places this block to the right in .some-existing-container */

  border: 1px solid purple; /* Highlighting */
}

.bigger {
  font-size: 4rem;
}

.stretched {
  align-items: stretch;
}
<p>Variant 1: Texts are aligned but items does not occupies the whole height:</p>
<div class="main">
  <div class="some-existing-container">
    <div class="menu">
      <div class="menu-item">
        <div class="menu-item-label">
          Home
        </div>
      </div>
      <div class="bigger menu-item">
        <div class="menu-item-label">
          Item1
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item2
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item3
        </div>
      </div>
    </div>
    <div class="other">
      Other
    </div>
  </div>
</div>
<p>Variant 2: Items of same-and-full height but texts are not aligned:</p>
<div class="main">
  <div class="some-existing-container">
    <div class="menu stretched">
      <div class="menu-item">
        <div class="menu-item-label">
          Home
        </div>
      </div>
      <div class="bigger menu-item">
        <div class="menu-item-label">
          Item1
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item2
        </div>
      </div>
      <div class="menu-item">
        <div class="menu-item-label">
          Item3
        </div>
      </div>
    </div>
    <div class="other">
      Other
    </div>
  </div>
</div>
Vtquan
  • 1
  • 1
-2

Have you tried using CSS Grid Layout? https://www.w3schools.com/css/css_grid.asp

Update :

Sorry, I did not noticed that you have tried Grid Layout already. But I do think that it is possible to achieve it with Grid Layout.

Would you mind posting the Grid Layout version of your code? I might be able to help you.

Thanks

redz0323
  • 56
  • 10
  • This is not an appropriate answer. Please save questions like this for the comments section above where you can ask the OP for more details before posting an answer. – Tanner Dolby Mar 05 '21 at 04:00
  • @Ta sorry, but I have a very low reputation as of the moment. I need 50 reputations in order to comment. – redz0323 Mar 05 '21 at 05:11
  • Oh yeah, I forgot you have to have 50 reputation before using the comments section. I apologize. In the future, try using the comments section when you have the reputation to do so for asking the OP more about their question. – Tanner Dolby Mar 05 '21 at 05:13
  • Yes, I tried Grid Layout but ran into the same issues: I'll update my OP with a Grid Layout snippet example... – CDuv Mar 05 '21 at 12:06
  • I added the Grid Layout example on the OP (https://jsfiddle.net/f156dau9/). – CDuv Mar 07 '21 at 01:17
-2
  • Because your wrapper "menu" didn't have its own height, set height for it, ex:
    .menu {
      height: 4rem;
      align-items: stretch
    }
  • Next, "menu-item" you should add:
    .menu-item {
      display: flex;
      align-items: center;
    }
Vtquan
  • 1
  • 1
  • It looks like it does not work: Can you provide a full code (HTML+CSS) snippet so that I can check? – CDuv Mar 05 '21 at 12:04