包含 float 的 inline-block 对齐问题原理详解?

发布于 2022-08-31 20:40:39 字数 2490 浏览 16 评论 0

有两个兄弟元素,分别是行内块级。其中一个内部元素浮动,导致父级元素上移

如下:

html<div style="border:1px solid blue; height:20px;">
    <div style="display: inline-block; border:1px solid red">
        <button>呵呵 1</button>
    </div>
    <div style="display:inline-block; border:1px solid #000000">
      <div style="border:1px solid green">
          <button style="float:left;">呵呵—— 1</button>
          <button style="float:left;">呵呵—— 2</button>
          <div style="clear:both;"></div>
      </div>
    </div>
  </div>

显示的结果是这样的

clipboard.png

有两种解决方式可以让父级元素对齐 ,求怎么解释?

  1. 父级元素的兄弟结点全部浮动;
  2. 给浮动元素加一个兄弟元素(此兄弟元素不浮动)

第一种

html<div style="border:1px solid blue; height:20px;">
    <div style="display: inline-block; border:1px solid red; float:left">
      <button>呵呵 1</button>
    </div>
    <div style="display:inline-block; border:1px solid #000000;  float:left">
      <div style="border:1px solid green">
          <button style="float:left;">呵呵—— 1</button>
          <button style="float:left;">呵呵—— 2</button>
          <div style="clear:both;"></div>
      </div>
    </div>
    <div style="clear:both;"></div>
</div>

显示的结果是这样的

clipboard.png


第二种

html<div style="border:1px solid blue; height:20px;">
    <div style="display: inline-block; border:1px solid red;">
      <button>呵呵 1</button>
    </div>
    <div style="display:inline-block; border:1px solid #000000;">
      <div style="border:1px solid green">
          <button>没有浮动</button>
          <button style="float:left;">呵呵—— 1</button>
          <button style="float:left;">呵呵—— 2</button>
          <div style="clear:both;"></div>
      </div>
    </div>
</div>

显示的结果是这样的

clipboard.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如何视而不见 2022-09-07 20:40:39

你沒有理解這個問題的本質。

在不指定 vertical-align 時,默認即基線對齊。然而由於該 box 當中既沒有 block level box 也沒有 text(比如全是 floating boxes,沒有規範的可以提取基線的地方),導致對齊時以該元素底部而非基線爲基準,又因爲元素底部在基線以下,就會出現對齊時上移的情況。

只要添加 text 或者添加 block 使其成爲 block container box 即可解決這一問題。

也可以父元素全設置浮動(浮動元素默認左上角對齊,相當於變相修改 vertical-align)

<!DOCTYPE html>
<title>box</title>

<style>
  .inline-block {
    display: inline-block;
  }
  .float {
    float:left;
  }
</style>

<div>
  <div class="inline-block">
    <div>Block</div>
  </div>
  <div class="inline-block">
    Baseline
    <div class="float">Float</div>
    <div class="float">Float</div>
  </div>
</div>

把 Baseline 換成僞元素,文字內容換成零寬度空格(\200B)或 Non-breaking space(\00A0)即可隱藏對齊用文字。

之所以不改 vertical-align 是因爲經常出現對齊有偏差的情況(主要是就 input 與 button 而言),而且如果不能保證高度一致,會導致無法基線對齊(比如問題中圖二)。


啊,纔看到樓主自己已經找到解決方案了(之前的注意力全在「呵呵」上,沒看見其它的是啥)。好在我本來就順便解釋了一下原理,答案懶得改了。

順便說一句,此時根本就不需要 clear:both,因爲

inline-blocks 會創建新的 Block formatting context,不影響外部的 float 和 clear

所以高度是會自適應浮動元素的。

附參考資料:

https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Visual_formatting_model


樓下認爲 float 會脫離文檔,這是不嚴謹的

正確的說法是 float 會讓元素脫離文檔流(normal flow)

float 並不會導致元素脫裏文檔,absolute 和 fixed 纔會。float 只會使元素脫離 normal flow,仍舊會佔據空間(比如導致 line box shrunk alongside)。

之所以會出現父元素不適應子浮動元素高度,是因爲父元素並沒有創建新的 block formatting context,浮動和清除的設置會影響到其它同一 block formatting context 的元素。

比如:

<div>
    <p><img class="float" />Some text</p>
    <p>Some text</p>
</div>

雖然 img 在第一個 p 當中,但是由於兩個 p 同處 div 所在的 block formatting context 中,所以第二個 p 仍舊會受到 img 的影響而 shrunk alongside。

只要設置第一個 p 的非 visible 的 visibility 屬性,或者設置 position 的 absolute/fixed,或者設置 inline-block,都會導致新的 block formatting context 創建,從而不影響後面的元素,並且高度自適應。

設置 clear 也是類似的原理,將之前的浮動設置清除,不再影響後面的元素。


inline-block 導致元素間空格是正確的表現,不預期這樣的行爲是出於對佈局機理的不熟悉。

正確的做法不是使用 font-size: 0(兼容問題),而是刪掉空格(對於 li 的 inline-block):

<ul>
  <li>
    <a href="#">Item</a>
  </li><li>
    <a href="#">Item</a>
  </li><li>
    <a href="#">Item</a>
  </li><li>
    <a href="#">Item</a>
  </li><li>
    <a href="#">Item</a>
  </li>
</ul>

或者使用 float、flexbox 實現。

漫雪独思 2022-09-07 20:40:39

我不知道楼主问这个问题是出于有这个需求?
个人觉得楼主并没有处理好,float和inline-block是解决块级元素并排的常见选择(楼主应该也是解决这个问题的吧)。解决了并排的问题的同时会带来新的问题:

float会导致元素脱离文档,不占据原有空间。为了解决这个问题,你需要清理float。虽然清理能让float的元素拥有正常文档流的大部分表现,但vertical-align这个属性却再也回不来了,你不管设置为什么,它都没有效果。

而inline-block也会带来问题,正如你所说,html中的换行带来的间隔。这时候你需要清除这个间隔,清除方式有很多种,我只说我最常用的一种:

html<style>
    /* 解决inline-block带来的间隔问题,思路是将间隔的字体设置为0,再还原非间隔的字体大小 */
    ul {
        font-size: 0;
    }
    ul > * {
        /* 任何不依赖于其父元字体的单位都可以,这里用的rem */
        font-size: 1rem;
    }

    /* 本该有的样式 */
    ul > li {
        display: inline-block;
        vertical-align: middle;
    }
</style>
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>

这种方式相比于float的方式,它不会让元素脱离文档,它是正常的文档流,但会不会有某个属性实效这样的东西,我就不知道了,目前从我的项目中来看是没有的。


对于float,我的说法有不少错误,详细信息请看评论

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文