问题描述
我有一个单行/行导航/菜单,其中一些项目具有更大的字体大小,但我希望所有项目的文本沿着基线和谐对齐。
我还需要项目对悬停在菜单的整个高度上做出反应,这样用户就不必瞄准较小的文本(这是针对子菜单,但不属于此问题的一部分)。
我尝试使用 FlexBox,但我无法混合使用 align-items: stretch
(全高)和 align-items: baseline
(文本对齐)
注意:菜单项的文本位于 menu-item-label
包装器中,因为我会向项目添加更多内容(下拉箭头、图片...),但重要的是文本对齐方式。
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>
我想将两者混合为下面的蒙太奇:
是否有可能(使用或不使用 JavaScript)?
我也尝试过网格布局但没有成功(请参阅 this JSFiddle)。
解决方法
我会保持基线对齐并考虑使用伪元素技巧来增加可悬停区域:
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>
这是我稍微修正你的 css 后的结果。
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>
您是否尝试过使用 CSS 网格布局? https://www.w3schools.com/css/css_grid.asp
更新:
抱歉,我没有注意到您已经尝试过网格布局。 但我确实认为可以通过网格布局来实现。
您介意发布代码的网格布局版本吗?我也许能帮到你。
谢谢
,- 因为您的包装“菜单”没有自己的高度,请为其设置高度,例如:
.menu {
height: 4rem;
align-items: stretch
}
- 接下来,您应该添加“菜单项”:
.menu-item {
display: flex;
align-items: center;
}