【问题标题】:Inline-Block inside Inline-block Invisible MarginInline-Block inside Inline-block 不可见边距
【发布时间】:2017-09-15 05:00:36
【问题描述】:

请参阅此笔以获取示例和一种解决方案:https://codepen.io/MaxViewUp/pen/YrXzRG

我有一个内联标题,其宽度将根据文本宽度而定,我在其中有一个 :after(或者如果你愿意,还有一个 div)和 inline-block,宽度为 70%。我使用 inline-blocks 是因为我有这个标题的 3 种变体(左、右和中),所以我只需更改文本方向即可更改标题。

问题: inline-block 元素在文本中有一个奇怪的不可见“margin-top”。我想知道为什么会发生这种情况以及更好的解决方案。我认为这与font-size(更大的字体大小更大的间距)有关,但我不确定。

到目前为止的解决方案:

  • font-size: 0 - 不是一个好的解决方案,因为它会弄乱 HTML;
  • :after 上的 display:blockfloat:left - 不是一个好的解决方案,因为文本对齐不会影响它;

如果有人确切知道为什么会发生这种情况,请解释一下。

CSS 代码:

.main-title {
  display: inline-block;
  font-size: 24px;
}
.main-title:after {
  content: '';
  display: inline-block;
  width: 70%;
  height: 2px;
  background: green;
}
.main-title-wrapper {
  margin: 20px 0;
}
.main-title-wrapper.right {
  text-align: right;
}
.main-title-wrapper.center {
  text-align: center;
}

注意 我想解决这个问题,但我真正需要的是发生这种情况的原因(文档等)。感谢您的帮助。

【问题讨论】:

    标签: html css font-size display


    【解决方案1】:

    每个 inline 或 inline-block 元素在其自己的行(如您的 :after)元素上的行为就像一行文本,因此受制于任何字体和字体的行高、垂直对齐和基线-您在父级上设置的大小(24px)。

    虽然它需要一个额外的元素,但您最初的示例解决方案是将文本包装在自己的元素中,将 0 字体大小应用于父元素,并将 24px 字体大小仅应用于文本元素(因此首先应用于仅行),如果您不想诉诸诸如负边距或负行高之类的技巧,这是最好的解决方案。

    这是适用于内联或内联块元素的排版 CSS 属性的摘要:https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align

    【讨论】:

    • 感谢详细描述的答案(迄今为止最好的)。您能否提供一些描述此内容的文档/文章的链接?
    • 这是一个非常详尽的排版 CSS 属性总结,因为它们适用于内联或内联块元素:iamvdo.me/en/blog/…
    • 谢谢,离线阅读不错。我认为问题已经解决了,但我会稍等片刻,直到问题得到很好的解决方案(代码替代)。
    【解决方案2】:
    .main-title{
        display: inline-block;
        position: relative;
        font-size: 24px;
            &:after{
                content: '';
                position: absolute;
                bottom: 0px;
                left: 0px;
                display: inline-block;
                width: 70%;
                height: 2px;
                background: green;
            }
    }
    

    使用position: relativeposition:absolute 怎么样?

    https://codepen.io/anon/pen/QqbwbJ

    【讨论】:

    • 解决了问题但不是一个有效的解决方案(需要改变2个元素来改变方向)
    • 感谢您尝试解决问题,但我真正想要的是发生这种情况的原因(文档等)
    【解决方案3】:

    您可以将inline-flexflex-direction: column 一起使用

    .main-title {
    	display: inline-flex;
    	font-size: 24px;
    	flex-direction: column;
    }
    .main-title:after {
    	content: '';
    	width: 70%;
    	height: 2px;
    	background: green;
    }
    .main-title.expected {
    	font-size: 0;
    }
    .main-title.expected > div {
    	font-size: 24px;
    }
    
    .main-title-wrapper {
    	margin: 20px 0;
    }
    
    .main-title-wrapper.right {
      text-align: right;
    }
    
    .main-title-wrapper.right .main-title {
    	align-items: flex-end;
    }
    
    .main-title-wrapper.center .main-title {
    	align-items: center;;
    }
    
    .main-title-wrapper.center {
      text-align: center;
    }
    
    * {
    	font-family: sans-serif;
    	font-weight: 300;
    	box-sizing: border-box;
    }
    CSS problem:
    
    <div class="main-title-wrapper">
     <div class="main-title">Normal</div>
    </div>
    
    <div class="main-title-wrapper">
     <div class="main-title">Normal - An Large text...</div>
    </div>
    
    <div class="main-title-wrapper right">
     <div class="main-title">Right - Lorem ipsum</div>
    </div>
    
    <div class="main-title-wrapper center">
     <div class="main-title">Center - Lorem ipsum</div>
    </div>
    
    <div class="main-title-wrapper">
     <div class="main-title expected">
      <div>This is what i expected:</div>
     </div>
    </div>

    【讨论】:

    • 不能解决问题 - afters 没有遵循对齐方式
    • 感谢您尝试解决问题,但我真正想要的是发生这种情况的原因(文档等)
    • @Maxwells.c 啊抱歉错过了对齐部分。您可以使用align-items 解决这个问题。更新了我的答案。
    • 这个 EDIT 解决了这个问题,但是 after 不遵循文本对齐:需要 2 个 css 规则。
    • @Maxwells.c 不客气。它与inline-block 项目的垂直对齐有关。您可以使用vertical-align: top 来移动那个条,但是.main-title 内部仍然有很大的空间。不知道为什么。
    【解决方案4】:

    使用 line-height 达到预期效果

    https://codepen.io/nagasai/pen/jGPEbX

    .main-title{
        line-height: 7px;
        display: inline-block;
        font-size: 24px;
    }
    

    ::after 伪元素的行高将从主标题类 div 继承
    请查看这篇文章以供参考 - http://www.testmycss.com/tips-and-tricks/css-before-pseudo-element-line-height/https://developer.mozilla.org/en-US/docs/Web/CSS/line-height

    【讨论】:

    • 这是迄今为止最好的解决方案
    • 感谢您尝试解决问题,但我真正想要的是发生这种情况的原因(文档等)
    • @Maxwells.c line-height 解释它,伪写在下一行,两行与 font-size 值具有相同的 line-height (它也解释了为什么 font-size:0;作品)。你可以减少一点间隙设置vertical-align:top到伪
    • 抱歉@Maxwells.c 回复晚了,::after 伪元素的行高将从主标题类 div 继承,不错的文章有示例供参考 - testmycss.com/tips-and-tricks/…
    【解决方案5】:

    使用相对定位并提供更大间距控制的解决方案:https://codepen.io/anon/pen/oGXXmV

    根据inline-block 的定义,您的:after 伪元素受制于与您的标题元素一致的文本大小属性。它只是在一个新行上,具有与标题文本相同的行高和其他属性。

    如果您只是减少标题的整体line-height,正如其他答案所建议的那样,您实际上只是将两行压缩到一行的空间中。这没有什么特别的问题,但可能会产生其他意想不到的副作用。

    此解决方案使用em,因此即使您将字体大小更改为24px 以外的其他值,它也不会相对于您的标题发生变化(强烈建议通常使用em,更易于访问和适应)。

    .main-title{
    	display: inline-block;
    	background: #fc0;
    	height: 1em; /* tweak this value to control the overall height */
    	font-size: 24px;
    }
    .main-title:after{
      content: '';
      display: inline-block;
      width: 70%;
      height: 2px;
      background: green;
      position: relative;
      top: -.85em; /* tweak this value to control distance of line below text */
    }

    【讨论】:

    • 这是一个很好的解决方案!我将在我的代码中使用它。我不会给出这个公认的答案,因为我真的很想解释这个问题,而帕特里克给出了一个很好的解释。感谢您提供好的解决方案。