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:
Is it even possible (with or without JavaScript)?
I have also tried with Grid layout without success (see this JSFiddle).
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>