【问题标题】:Vertically align text of same-height blocks along a shared baseline (supporting mixed font size)沿共享基线垂直对齐相同高度块的文本(支持混合字体大小)
【发布时间】:2021-06-03 17:32:50
【问题描述】:

我有一个单行/行导航/菜单,其中一些项目的字体较大,但我希望所有项目的文本沿基线和谐对齐。

我还需要项目对悬停在菜单的整个高度做出反应,这样用户就不必瞄准较小的文本(这是子菜单,但不属于这个问题的一部分)。

我尝试使用 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)。

【问题讨论】:

    标签: css flexbox vertical-alignment baseline


    【解决方案1】:

    我会保持基线对齐并考虑使用伪元素技巧来增加可悬停区域:

    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>

    【讨论】:

    • 感谢您的解决方案:效果很好!但是我在菜单中有一个我没想到会被这个解决方案破坏的功能(所以我没有把它放在原始帖子中,我的错):我有一个子菜单(@987654326 内的&lt;ul&gt;&lt;li /&gt;...&lt;li /&gt;&lt;/ul&gt; @ 块)仅在菜单项悬停时出现在菜单项下方。 .menu 上的 overflow: hidden; 使其不可见(参见 example JSFiddle)。你认为有办法让你的解决方案与这个“子菜单功能”兼容吗?
    • 抱歉:新的 JSFiddle 具有更多实际希望的子菜单表示:jsfiddle.net/069utjvd
    • @CDuv 抱歉,但我认为这个解决方案不适用于 submeny。我建议您根据该要求编辑您的问题(并删除已接受的答案),您可能会得到更多想法。
    【解决方案2】:

    这是我稍微修复了你的 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>

    【讨论】:

      【解决方案3】:

      您是否尝试过使用 CSS 网格布局? https://www.w3schools.com/css/css_grid.asp

      更新:

      抱歉,我没有注意到您已经尝试过网格布局。 但我确实认为可以通过 Grid Layout 来实现。

      您介意发布代码的网格布局版本吗?我也许可以帮助你。

      谢谢

      【讨论】:

      • 这不是一个合适的答案。请将此类问题保存到上面的 cmets 部分,您可以在发布答案之前向 OP 询问更多详细信息。
      • @Ta 抱歉,但目前我的声誉很低。我需要 50 个声望才能发表评论。
      • 哦,是的,我忘了你必须有 50 声望才能使用 cmets 部分。我道歉。将来,当您有声誉时,请尝试使用 cmets 部分向 OP 询问有关他们的问题的更多信息。
      • 是的,我尝试了网格布局,但遇到了同样的问题:我将使用网格布局 sn-p 示例更新我的 OP...
      • 我在 OP (jsfiddle.net/f156dau9) 上添加了网格布局示例。
      【解决方案4】:
      • 因为您的包装“菜单”没有自己的高度,请为其设置高度,例如:
          .menu {
            height: 4rem;
            align-items: stretch
          }
      
      • 接下来,您应该添加“菜单项”:
          .menu-item {
            display: flex;
            align-items: center;
          }
      

      【讨论】:

      • 好像不行:能否提供完整的代码(HTML+CSS)sn-p让我检查一下?
      猜你喜欢
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-25
      • 1970-01-01
      • 2018-06-03
      • 2017-12-26
      相关资源
      最近更新 更多