CSS秘密花园: 内容尺寸

CSS Secrets》是@Lea Verou最新著作,这本书讲解了有关于CSS中一些小秘密。是一本CSSer值得一读的一本书,经过一段时间的阅读,我、@南北@彦子一起将在W3cplus发布一系列相关的读后感,与大家一起分享。

CSS Secrets

问题

大家都知道,如果不显式的给一个元素设置height值,它将会根据元素的内容自动调整。如果我们要想要给元素的宽度也有一个类似的行为呢?例如,你们假设有一个HTML5的标签figure,其里面的数据如下所示:

<p>Some text [...]</p>
<figure>
    <img src="adamcatlace.jpg" />
    <figcaption>
        The great Sir Adam Catlace was named after
        Countess Ada Lovelace, the first programmer.
    </figcaption>
</figure>
<p>More text [...].</p>

给它们设置一些基本的样式,比如给figure加个边框。默认情况,我们看到的效果如下图所示:

内容尺寸

我们要让figure中的宽度和图像的宽度一样(可能大小不同)和水平居中。现在的效果并不是我们想要的效果:文本一行显示比图像更长。我们如何使figure的宽度和包含的图像宽度一样,而不是取决他父元素的宽度呢?从我们平时工作当中的经验可以得知,要实现有这样的效果我们有多种CSS方式可以实现,但通常都有各自的副作用:

<figure>设置为浮动元素,这样能得到正确的宽度,但布局也将改变,这并不是我们想要的方式,如下图所示:

内容尺寸

<figure>设置display:inline-blockfigure宽度大小是基于其内容,但也不是我们想要的效果,如下图所示:

内容尺寸

此外,即使宽度的计算达到我们期望,但让figure水平居中也是相当的麻烦。需要先给其父元素设置text-align:center,然后给父元素的其他子元素(如p,ul,ol,dl等)设置text-align:left

作为最后的手段,开发人员会给<figure>设置一个固定宽度或者max-width值,并且给figure > img设置max-width: 100%;。然而,如果figure过小时,我们依旧没有允分利用好可用的空间,而且不能做到响应的效果。

有没有CSS能解决这个问题,或者说我们放弃解决这个问题,还是写个JS脚本来给figure设置宽度呢?

解决方案

一个相对较新的规范 CSS Intrinsic & Extrinsic Sizing Module Level 3widthheight定义了一些新的关键词,其中一个非常有用的是min-content。这个关键词可以给我们获取元素盒子的最大宽度(例如,图片或元素的宽度)。这正是我们需要的东西!现在,他们可以给figure设置适合的宽度并且让他们水平居中,而且这仅仅只要简单的两行代码:

figure {
    width: min-content;
    margin: auto;
}

max-content和使用display:inline-block效果等同,除此之外,还有一个值fit-content,他的表现行为和float的行为是一样的。(我们常用的是min-content,但并不总是使用这个属性)。

运行上面的代码之后,你可以看到下图的结果:

内容尺寸

为了能让不支持min-content的浏览器能更好的呈现内容,提供了一个优雅降级,可以使用max-width,如下所示:

figure {
    max-width: 300px;
    max-width: min-content;
    margin: auto;
}
figure > img { 
    max-width: inherit; 
}

在现代浏览中,后面的max-width会覆盖前面的,当图片过大时,max-width:inherit;也会没效果。

Dudley Storey在他的博客中介绍了如何使用min-content

如需转载,烦请注明出处:http://www.w3cplus.com/css3/css-secrets/intrinsic-sizing.html

返回顶部