将元素浮动到底部角

Avatar of Temani Afif
Temani Afif

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费信用额度!

需要将元素布局到右侧或左侧,以便文本环绕它?对于float 属性来说,这是一项简单的任务。但是,如果我们也希望将该元素(我们称之为图像)推到底部角之一,该怎么办?听起来有点棘手,对吧?我们可能需要 JavaScript?

不,几行(棘手的)CSS 就可以做到!以下仅使用 CSS 的解决方案将使您的图像粘贴到底部角,无论大小和内容如何。

调整包装元素的大小,见证神奇的效果

让我们剖析代码。

标记和布局

我们需要一个包装元素来包含所有内容,并且我们将对其使用flexbox。Flexbox 允许我们依赖默认的stretch 对齐方式,以便以后使用height: 100%

<div class="wrapper">
  <div class="box">
    <div class="float"><img></div>
    Lorem ipsum dolor ...
  </div>
</div>
.wrapper {
  display: flex;
}

.float {
  float: right;
  height: 100%;
  display: flex;
  align-items: flex-end;
  shape-outside: inset(calc(100% - 100px) 0 0);
}

.wrapper 内的.box 是我们的弹性项目。我们不需要对该框应用任何特定的 CSS。它定义了包装器的高度,并且同时被拉伸到相同的高度。此行为将为我们提供一个“参考高度”,子元素可以使用该高度。

来自规范

如果弹性项目具有align-self: stretch,则重新布局其内容,将此使用的大小视为其确定的交叉大小,以便可以解析百分比大小的子元素。

关键词是确定的,它允许我们在框元素内部安全地使用百分比(%)高度。

现在是浮动元素

我们的.float 元素将占据文本内容旁边的整个高度,这要归功于我们上面详细介绍的高度计算。在此元素内部,我们使用 flexbox 对齐方式将图像推到底部。

A paragraph of lorem i-sum text with a small square image to the right of the text. The image is located at the bottom right of the text and the space above the image is empty.
图像浮动到右侧,但其上方的可用空间阻止了内容环绕它。

现在是真正的技巧,使用shape-outside 属性。以下是MDN 的定义

shape-outside CSS 属性定义了一个形状(可能是非矩形的),相邻的内联内容应围绕该形状换行。默认情况下,内联内容围绕其边距框换行;shape-outside 提供了一种自定义此换行的方式,从而可以使文本围绕复杂对象而不是简单的框换行。

换句话说,shape-outside 设置内容围绕元素边界框流动的方向。

它采用许多值。其中一个是inset() 函数,再次,根据 MDN

定义一个内嵌矩形。当提供所有前四个参数时,它们分别表示从参考框向内开始的顶部、右侧、底部和左侧偏移量,这些偏移量定义了内嵌矩形边缘的位置。

因此,使用shape-outside: inset(calc(100% - X) 0 0),我们可以创建一个从图像顶部开始的内嵌矩形。顶部等于100% - X,其中X 是图像高度,100%.float 元素的高度。这允许文本在图像顶部的可用空间内换行。这是响应式的,此外我们还可以轻松地在左侧和右侧之间切换(通过调整float 属性)

就是这样!唯一的主要警告是您需要知道图像的高度。

让我们优化标记

我们仍然可以稍微优化我们的代码并删除图像周围的额外包装器。

<div class="wrapper">
  <div class="box">
    <img class="float">
    Lorem ipsum dolor ...
  </div>
</div>

然后我们的 CSS 将变为

.wrapper {
  display: flex;
}

.float {
  float: right;
  height: 100%;
  width: 100px;
  shape-outside: inset(calc(100% - 100px /*height */) 0 0);
  object-fit: contain;
  object-position: bottom;
}

由于我们删除了额外的包装器,因此我们需要另一种技术将图像放置到底部角。为此,我们使用object-fitobject-position,但必须显式指定图像的宽度。

使用此方法,我们需要知道图像的宽度和高度,这与前面的代码不同,在前面的代码中只需要高度。

想要更多?

我们可以进一步扩展此概念以适应更复杂的情况。例如,我们可以将图像浮动到右侧,但将其固定在框的中间,使用justify-content: center:并通过将shape-outsideinset(calc(100% - X) 0 0) 更改为inset(calc(50% - X/2) 0 0) 将我们的内嵌矩形调整到中间。

我们也可以在两个底部角浮动两个图像

这里没有什么复杂的东西。我只是简单地使用了相同的浮动元素两次,一次在右侧,一次在左侧。当我们可以在所有四个角放置图像时,为什么要止步于两个角呢?

这里采用了相同的基本思想,但我们也依赖于顶部图像的通用浮动功能。但是,您会注意到,这就是概念开始略微失效的地方,并且根据包含框的大小,我们会得到一些不需要的溢出。我们可以使.float 元素的高度大于 100%,并应用一些“魔法数字”通过调整图像的填充和边距来使事情变得平滑。

您知道shape-outside 接受radial-gradient() 作为值吗?我们可以用它来放置如下所示的圆形图像

渐变的透明部分是文本可以进入的可用空间。您可能已经注意到,我们也对图像应用了border-radiusshape-outside 属性只会影响.float 元素,我们需要手动调整图像的形状以遵循shape-outside 定义的形状。

既然我们已经这样做了,让我们将其与我们之前使用justify-content: center 将图像固定到框垂直中心的示例结合起来。

另一个radial-gradient() 以及另一个border-radius 配置。

我们可以改用linear-gradient() 来为包装区域制作三角形形状

这与我们用于radial-gradient() 的想法相同。最大的区别是我们使用clip-path 而不是border-radius 来裁剪我们的图像。

并且,既然我们对其他元素进行了此操作,让我们使用justify-content: center 的想法将图像固定到框右侧边缘的垂直中心。

我们在上面的演示中使用了conic-gradient()shape-outside 来定义三角形形状,并使用clip-path 在图像上获得类似的形状。

如果图像仅用于装饰(如果在 HTML 中不需要它用于 SEO 目的),则所有这些示例仍然可以使用更少的代码进行优化。让我们用伪元素替换.float 元素,并改为将图像应用为背景

我们使用mask 来显示我们需要的图像部分,并且,猜猜看,它使用了与shape-outside 相同的值!因此,我们所要做的就是为形状定义一个值。

就是这样!

这里有很多可能性,不仅可以将矩形放置在角上,还可以使用基本相同的代码结构将任何类型的形状放置在任何位置。我们只需要

  • 调整shape-outside 属性以定义形状
  • 对图像应用一些样式以遵循先前定义的形状如果我们使用伪元素版本,则对mask 应用相同的值

然后所有内容都保持在原位,即使在响应式设计中也是如此。