CSS - 使段落文本环绕图像而不浮动

时间:2013-11-20 01:02:45

标签: css

我可以简单地使用float来实现<img>元素的文本环绕,并且我理解<img>是内联元素,而<p>是块级元素,所以要使它们内联,我应该使<p>成为内联元素,或者使用<span>代替。

问题在于,如果我将它们全部视为内联元素,它会在图像旁边和文本顶部留下一个巨大的空白区域。

enter image description here

我想知道导致空白的原因。

这是我的JS Fiddle

7 个答案:

答案 0 :(得分:9)

这个问题似乎关注的原因是什么,所以我会关注内部运作:

CSS 2.1规范的Visual formatting model部分描述了inline formatting contexts

  

在内联格式化上下文中,框从水平排列,一个接一个,从包含块的顶部开始。这些框之间会考虑水平边距,边框和填充。 框可以以不同的方式垂直对齐:它们的底部或顶部可以对齐,或者它们中的文本的基线可以对齐。包含形成一条线的框的矩形区域称为线框。

他们描述的属性是vertical-align,它采用了许多不同的值,baseline是默认值。这就是为什么你的两个inline元素就像它们一样出现,坐在基线上。您可以将<p>更改为vertical-align: top,第一行文字的顶部将与图片顶部对齐。但是,您仍然会在第一行文本与以下行之间产生差距。

这是因为文本将一个行框垂直呈现到下一个行框。无论第一行的行框是否大于其余行,它仍然会一次流动一个行框。这是这个概念的可视化:

enter image description here

理解这一点的另一个重要概念是<img>替换内联元素,这意味着它的外观由文档外部的外部资源构成。 替换的内联元素可以采用height值,而所谓的非替换内联(如<span>)元素则不能。这就是为什么<img> <span>foo</span>的行为可能与<span>foo</span> <em>bar</em>不同(因为图像具有固有高度),即使它们都是内联元素。想象一下,将图像的高度设置为文本的x高度 - 它将有效地呈现与图像相同的颜色,但在这种情况下,它的行为完全符合您的预期:

img {
  height: 10px;
  }

p { 
  display: inline;
  }
<div>
    <img src="http://placehold.it/100x100/E8117F/000.png">
    <p>hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello</p>
</div>

这可能是一些混乱发生的地方。如果您可以想象这些线条,那么您可以理解内联元素不会像浮动元素那样表现。

将这些信息与规范中有关floats的内容进行比较:

  

浮动是一个在当前行上向左或向右移动的框。 浮动(或“浮动”或“浮动”框)最有趣的特征是内容可能沿其侧面流动(或禁止通过'clear'属性这样做)。 内容沿左浮动框的右侧向下流动,沿右浮动框的左侧向下流动。

     

浮动框向左或向右移动,直到其外边缘接触包含块边缘或另一个浮动边缘的外边缘。 如果有行框,则浮动框的外部顶部与当前行框的顶部对齐。

虽然我无法向你描述电子发生了什么,但我希望这是理解为什么这些不同场景呈现它们的方式的良好起点。

答案 1 :(得分:4)

尝试将图像设为绝对图像,然后使用相邻的兄弟选择器将填充添加到下一个段落标记以补偿图像。在这里小提琴:http://jsfiddle.net/r2MFz/3/

这是CSS。

img:first-of-type + p {
  padding-left: 110px;
  display: inline-block;
}

p {
  padding-bottom: 20px;
}

img {
  position: absolute;
  top: 0;
  left: 0;
}

这变得非常有创意,除此之外,除了浮动之外我无法想到任何其他选项。

答案 2 :(得分:2)

正如您所说,您可以使用float轻松解决此问题。本文讨论了形状和浮动,因此它是一个很好的参考: How to wrap text around an image using HTML/CSS

因此,如果您只是询问导致空白的原因,那么您真正要问的是浏览器的解析和渲染过程与浮点数有什么关系。简而言之,虽然标记化和解析比这更复杂,但基本概念仍然是浏览器以从左到右,从上到下的格式将输出呈现到屏幕上。因此,如果您将图像标记放在第一位,作为可继承的内联元素,它将声明所需的屏幕空间(在屏幕上呈现)以便显示。我们从左到右,从上到下渲染,因此渲染指针结束的最后一个点是图片的右下角。如果修改下一个标记,在同一树级别上也要内联,它只知道继续图像指针停止的位置。指针说,这是我应该开始在段落标签中绘制单词的地方。因为我知道段落标记的默认值,所以我会跳起来并将字母渲染到适当的高度和宽度。

Float修复此问题,因为浮动框位于正常流中,然后从流中取出并尽可能向左或向右移动。因此,段落应该继续呈现的指针会改变位置。

以下是这方面的好消息: http://taligarsiel.com/Projects/howbrowserswork1.htm#Parsing_general http://www.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/

答案 3 :(得分:2)

你需要使图像内联和浮动,而不是文本这是使图像表现出来的方式,至少从98开始,可能更早,但我只是开始使用文字处理器,因为&#39; 98。由于某种原因,图像决定文本流; - )

&#13;
&#13;
img {
    float:left;
    display:inline-block;
    margin:10px;
   
}
&#13;
<div class="hoge">
    <img src="http://dummyimage.com/100x100/000/fff">
        <p>hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello</p>
</div>
&#13;
&#13;
&#13;

答案 4 :(得分:1)

空白的原因可能是由于缺少vertical-align属性。如果包含vertical-align: top属性,则段落的第一行将移至顶部。唯一的问题是仍然有一个空白。

这就是我的意思:http://jsfiddle.net/7t633/5/

<强> CSS

p {
    display: inline;
    vertical-align: top;
}

但如果您为imgp更改了CSS,则可以在不使用float属性的情况下实现float效果。唯一的问题是文本不会环绕图像。您必须使用float属性来实现此目的。

这就是我的意思:http://jsfiddle.net/7t633/6/

<强> CSS

img {
    display: inline;
    position: absolute;
}
p {
    display: inline-block;
    margin-left: 105px;
    vertical-align: top;    
}

答案 5 :(得分:1)

我不认为还有另一个CSS解决方案可以不用浮动来包装它。你可以绝对定位物品,但那时它们会并排,而不是包装。您可以尝试使用此jQuery插件来包装文本。你甚至可以包裹弯曲的图像:

http://baconforme.com/

答案 6 :(得分:-2)

这不是CSS,但在img标签上使用align =“left”是另一种选择。

<img src="http://dummyimage.com/100x100/000/fff" align="left">