自适应宽度是指在未明确设定容器的宽度(或外边距设为auto)的情况下,容器的宽度会根据特定情况自行调整。然而,这种调整结果往往并非我们所期望的。W3C规范中描述了几种shrink-to-fit的情况,包括浮动元素、绝对定位非替换元素和绝对定位替换元素等。
CSS将HTML元素分为两类:不可替换元素和可替换元素。可替换元素是指其展现不是由CSS控制的外部元素,如img、object、video以及textarea、input等表单元素。而不可替换元素则相反。此外,使用了CSS content属性插入的对象被称为匿名可替换元素。
最常见的shrink-to-fit情况是不可替代元素浮动时的自适应宽度(Floating, non-replaced elements)。以一个例子为例:html&css代码定义了一个outer容器,背景为黑色且宽度为800px,内部容器inner无宽度且左浮动,inner里有两个小块sub1和sub2。问题在于,inner、sub1和sub2的具体宽度是多少?
先看效果图再回答:结果可能出乎意料,inner(红色背景)的宽度并不是outer(黑色背景)的宽度(正常情况下应该可以继承父容器的宽度),因此sub1和sub2比预想的要小得多。
在回答这个问题之前,我们先尝试修改一下布局,看看能否找到出现问题的原因。经过调试,发现两种最简单的方案可以解决这个问题:
1. 为inner元素添加宽度属性`width: 100%;`;
2. 取消inner元素的浮动。
修复后的效果如下:
这的确是我们期望的结果,但却巧妙地“躲过了”不可替换元素浮动的场景。实际上,我曾多次遇到过这种问题,但通常都是利用上述两个方案进行尝试,但并不了解真正的原因。因此,我还是阅读了W3C关于这一方面的规范,具体描述如下:
首先,英文描述存在一些问题,如"Roughly"和"CSS 2.1 does not define the exact algorithm",让人哭笑不得。此外,还给出了一个名为shrink-to-fit的公式:
min(max(preferred minimum width, available width), preferred width)
然而,实际上这三个值的计算方法并不清楚。
在网上搜索后,发现很多人都遇到了这个问题,但同样也搞不清楚规范的具体含义。有人将上述描述进行了翻译,大家可以参考一下:
CSS2.1并未给出preferred minimum width、available width和preferred width确切的算法。通常情况下,将内容中非明确换行的部分强制不换行来计算preferred width;反之,尝试将内容尽可能换行以得到preferred minimum width;available width即为该元素的包含块宽度减去'margin-left','border-left-width','padding-left','padding-right','border-right-width','margin-right'的值以及任何存在的纵向滚动条宽度。
这段翻译可能让很多人感到困惑。经过近一个小时的摸索,我终于理清了这段晦涩的英文描述:
在CSS布局中,我们经常会遇到一些需要自适应宽度的情况。这时候,我们需要关注的是元素的preferred minimum width,即元素内容强制不换行后的最大宽度。这个宽度可以通过以下计算方式得出:
让元素内容强制不换行后的最大宽度即为shrink-to-fit后的宽度。具体操作方法如下:
以一个简单的例子为例,假设我们有一个名为inner的元素,其中包含一个名为sub1的内容。由于sub1的内容宽度不够,所以会被换行显示。为了让sub1的内容完全展示在一行中,我们需要将其强制不换行。这时,sub1的宽度调至100%时恰好足够用一行来展示其内容,此时content的宽度就是inner自适应后的宽度。
为了演示这个过程,我们可以逐步增加sub1的宽度,直到其宽度达到100%。通过这种方法,我们可以观察到在哪个宽度下,content的宽度刚好等于inner自适应后的宽度。如图所示:
总结一下,对于浮动或者特殊的定位方式,推荐显式地设置容器宽度,以避免出现意想不到的结果。这样可以确保元素能够根据容器的宽度进行正确的布局和显示。如果没有明确设置容器宽度,可能会导致元素无法正常显示或者布局出现问题。因此,在实际应用中,我们需要注意为容器设置合适的宽度,以保证布局的正确性和一致性。