CSS浮动:如何将浮动保持在它所属的文本附近?

问题描述 投票:12回答:10

我有一个包含步骤的程序。一些步骤伴随着图像。

    <p class="imagefloatright"><img src="step 1.png"/></p>
    <ol>
        <li>
          <p>Step 1</p>
          <p class="imagefloatright"><img src="step 2.png"/></p>
        </li>
        <li>
          <p>Step 2</p>
          <p>Step 3</p>
        </li>
    </ol>

和我的CSS:

p.imagefloatright img {
    float: right;
    clear: both;
}

这是默认输出。图像不会与它们所属的步骤保持一致,步骤2的文本放在图像1旁边:

enter image description here

我希望属于第2步的图像与第2步垂直对齐:

enter image description here

过去,我通过在每个浮动图像之前插入一个高度为0的全宽度块,在XSL-FO中实现了我想要的结果。

我可以使用CSS命令实现我想要的布局吗?或者,在将CSS应用于HTML之前,是否需要在HTML中插入块?

css css-paged-media
10个回答
2
投票

清除包含动态内容的浮动,即。图像可以具有动态高度,您需要清除父元素本身。

.imagefloatright {
  clear: both;
}
.imagefloatright img {
  float: right;
}

这意味着您需要在包含浮动元素的元素上使用clear


为简洁起见,我会将其重命名为:

.clearfix {
  clear: both;
}
.float-right {
  float: right;
}

HTML

<p class="clearfix"><img class="float-right" src="step 1.png"/></p>
<ol>
    <li>
      <p>Step 1</p>
      <p class="clearfix"><img class="float-right" src="step 2.png"/></p>
    </li>
    <li>
      <p>Step 2</p>
      <p>Step 3</p>
    </li>
</ol>

这是一个demo


0
投票

您可以在after标签中使用li伪元素来获取浮动元素的高度。此外,您必须指定您只想使用>选择器浮动li标签内的元素。

ol {
  padding: 0;
}

li {
  padding: 10px;
  list-style: none;
  background: #eee;
  margin: 10px 0;
  width: auto;
}

li:after {
  content: '';
  display: table;
  clear: both;
}

li > p {
  width: 25%;
  float: left;
}

p {
  margin: 0;
}
<p><img src="http://fpoimg.com/300x300"/></p>
<ol>
  <li>
    <p>Step 1</p>
    <p><img src="http://fpoimg.com/300x300?text=Step1"/></p>
  </li>
  <li>
    <p>Step 2</p>
    <p>Step 3</p>
  </li>
</ol>

1
投票

你应该在clear元素上使用p属性,但是在你想要停止浮动的地方创建另一个元素。

p.imagefloatright img {
    float: right;
}

.clear {
    clear:both;
}
<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p>Step 1</p>
<div class="clear"></div>
<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p>Step 2</p>
<div class="clear"></div>

顺便说一句,这里有一个代码片段,显示了更好的步骤布局(从我的角度来看),这更符合逻辑,每一步都是一个正确定位图像和文本的块。

p.imagefloatright {
    clear:both;
}

p.imagefloatright img {
    float: right;
}
<p class="imagefloatright">
  Step 1
   <img src="http://via.placeholder.com/80x80"/>
</p>

<p class="imagefloatright">
  Step 2
  <img src="http://via.placeholder.com/80x80"/>
</p>

如果您仍希望在单独的p元素中包含文本,则可以将所有步骤作为div元素,其中包含正确样式的段落和图像。我也在display:inline-block元素上应用p以防止它占据整个宽度。您可以这样做或使用span而不是p

.imagefloatright {
    clear:both;
}

.imagefloatright p {
    display: inline-block;
    margin: 0;
}

.imagefloatright img {
    float: right;
}
<div class="imagefloatright">
  <p>Step 1</p>
   <img src="http://via.placeholder.com/80x80"/>
</div>

<div class="imagefloatright">
  <p>Step 2</p>
  <img src="http://via.placeholder.com/80x80"/>
</div>

1
投票

如果每个具有图像的步骤只有一个图像,并且图像不会被多个步骤共享,则可以编写一个选择器以使以下步骤清除每个浮动图像,但它非常严格:

p.imagefloatright img {
  clear: both;
  float: right;
}

p.imagefloatright + p:not(.imagefloatright) + p {
  clear: both;
}
<p class="imagefloatright"><img src="https://placehold.it/100x100"/></p>
<p>Step 1</p>
<p class="imagefloatright"><img src="https://placehold.it/100x100"/></p>
<p class="imagefloatright"><img src="https://placehold.it/100x100"/></p>
<p>Step 2</p>
<p>Step 3</p>

如果步骤和图像之间没有严格的一对一关系,那么您需要战略性地将clear属性应用于特定步骤。


1
投票

这是一个使用flexbox的简单方法:

ol {
  list-style: none;
  padding:0;
  margin:0;
}

li {
  display: flex;
  /*for illustration*/
  border:1px solid;
  padding:5px;
}

img {
  margin-left: auto;
}
<ol>
  <li>
    Step 1
    <img src="https://placehold.it/100x100">
  </li>
  <li>
    Step 2
  </li>
  <li>
    Step 3
  </li>
  <li>
    Step 4
    <img src="https://placehold.it/100x100">
  </li>
</ol>

1
投票

解决方案1:使用Flex

我建议使用flexjustify-content: space-between使用它的唯一缺点是,如果你支持IE10这样的旧浏览器 - 那么你可以检查https://caniuse.com/#search=flex获取更多信息。

至于space-between很简单,就像MDN一样

物品沿着主轴均匀地分布在对准容器内。每对相邻物品之间的间距是相同的。第一项与主开始边齐平,最后一项与主端边齐平。

意思是,它将有一个第一个子节点与父节点的开头对齐,最后一个子节点与末尾对齐,剩余空格在其余子节点中平均分配(如果存在),如果img,它将为您提供所需的布局无论有多少孩子存在divs,它总是最后一个孩子。

就个人而言,我会发现使用flex是最方便的,也是最简洁的方法之一,可以在页面上“定位”和“布局”不同的元素。

你可以找到下面的代码和一个工作小提琴here

HTML

<ol class="step-list">
  <li class="step">
    <p>Step 1</p>
    <img src="https://placehold.it/150x150?text=Step1" alt="">
  </li>
  <li class="step">
    <p>Step 2</p>
  </li>
  <li class="step">
    <p>Step 3</p>
  </li>
  <li class="step">
    <p>Step 4</p>
    <img src="https://placehold.it/150x150?text=Step4" alt="">
  </li>
</ol>

CSS

.step-list {
  list-style: none;
}

.step {
  display: flex;
  justify-content: space-between;
}

解决方案2:使用Float

你仍然可以使用float但在这种情况下你需要清除p而不是img并浮动它。

由于包含元素的所有元素都是浮动的,所以将clearfix添加到li标记是不重要的,不要崩溃到任何你可以找到更多信息here

所以你的代码会喜欢这个,你可以找到一个工作小提琴here

HTML

<ol class="step-list">
  <li class="step">
    <p>Step 1</p>
    <img src="http://placehold.it/150x150?text=Step1" alt="">
  </li>
  <li class="step">
    <p>Step 2</p>
  </li>
  <li class="step">
    <p>Step 3</p>
  </li>
  <li class="step">
    <p>Step 4</p>
    <img src="http://placehold.it/150x150?text=Step4" alt="">
  </li>
</ol>

CSS

.step-list {
  list-style: none;
}

.step img {
  float: right;
}

.step p {
  float: left;
}

/*This is what is called a clearfix solution, for the floating problem*/
.step::after {
  content: "";
  display: block; 
  clear: both;
}

如果有什么不清楚的话,不要再犹豫了。


0
投票

clearfix应该有所帮助。 :

.clearfix:after {
  display: block;
  content: "";
  clear: both;
}

和HTML:

<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p class="clearfix">Step 1</p>
<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p class="clearfix">Step 2</p>
<p>Step 3</p>

0
投票

你可以用它

 <p>
    <span class="left">1</span>
       <img class="right"  src="http://via.placeholder.com/90x90" alt="">
  </p>

   <p>
    <span class="left">2</span>
       <img class="right"  src="http://via.placeholder.com/90x90" alt="">
  </p>

p{
  display:inline-block;
    margin-bottom:5px;
    width:100%;
}
p .left{
  float:left;
  margin-bottom:55px;
}
p .right{
 float:right;
}

https://jsfiddle.net/jlbarcelona/vcmdo7uy/106/


0
投票

为什么不用伪元素?

p, .imagefloatright img { margin: 0 0 .25em; }

.imagefloatright img {
  float: right;
}

.imagefloatright::before {
  clear: both;
  content: '';
  display: block;
}
<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p>Step 1</p>
<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p>Step 2</p>
<p>Step 3</p>
<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p>Step 4</p>
<p>Step 5</p>

你必须玩::before::after伪元素。另一种解决方案可能如下:

p, .imagefloatright img { margin: 0 0 .25em; }

.imagefloatright img {
  float: right;
}

.imagefloatright + p::after {
  clear: both;
  content: '';
  display: block;
}
<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p>Step 1</p>
<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p>Step 2</p>
<p>Step 3</p>
<p class="imagefloatright"><img src="http://via.placeholder.com/80x80"/></p>
<p>Step 4</p>
<p>Step 5</p>

以下所有步骤是否属于图像或不应该?这取决于 ;)


0
投票

这很容易做到。使用css float属性时,必须将overflow与其父元素一起使用。在你的情况下:

p.imagefloatright{
   overflow: auto;
}

必须解决这个问题。了解更多关于https://www.w3schools.com/css/css_float.asp的信息

© www.soinside.com 2019 - 2024. All rights reserved.