【问题标题】:CSS floats: how to keep the float near the text it belongs to?CSS浮动:如何将浮动保持在它所属的文本附近?
【发布时间】:2018-09-14 15:40:11
【问题描述】:

我有一个由步骤组成的程序。一些步骤附有图像。

    <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 旁边:

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

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

我可以使用 CSS 命令实现我想要的布局吗? 还是在将 CSS 应用到 HTML 之前,我需要在 HTML 中插入一个块?

【问题讨论】:

  • 它需要浮动吗?因为它可以在没有的情况下完成
  • 浮动不是绝对要求,如果您有不需要它的解决方案,请继续。
  • 我也可以制作任何 HTML 结构?
  • 是的,我正在考虑修改结构。

标签: css css-paged-media


【解决方案1】:

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

.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

【讨论】:

    【解决方案2】:

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

    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>

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

    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 元素,其中包含正确样式的段落和图像。我还在p 元素上应用display:inline-block 以防止它占据整个宽度。您可以这样做或使用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>

    【讨论】:

    • 但是为什么呢? clear 属性旨在无需专用清除元素即可使用 - 替代
    • 它应该在浮动元素之后而不是之前。我现在将用另一个例子扩展我的答案。
    • 是的,您不需要单独的元素 - 您可以将 clear 属性应用于该元素所在位置之后的任何一个。
    • 同意,但在作者的情况下,他有类似列表的东西。因此,在每个step 之后,他都有另一个具有相同 CSS 和浮动的。这就是为什么我决定在步骤之间添加元素。
    • 我有一份清单。我的例子太简单了,我会更完整的。
    【解决方案3】:

    如果每一步都有一张图片,并且一张图片不会被多个步骤共享,你可以编写一个选择器来让 以下步骤清除每个浮动图像,但它非常僵硬:

    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:1。
    • @Hobbes:如果这意味着会有一些没有图像的步骤,这仍然有效。如果某些步骤将有多个图像,但步骤之间不会共享图像,则选择器 p.imagefloatright + p:not(.imagefloatright) + p 应该可以工作。但总的来说,当您的所有元素都参与同一个流程并且您没有办法划分步骤时,很难解决浮动问题。许多其他答案都建议重组您的标记,这确实是最干净的解决方案。
    【解决方案4】:

    这是一个使用 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>

    【讨论】:

      【解决方案5】:

      解决方案 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,但在这种情况下,您需要清除 p 而不是 img 并将其浮动。

      由于包含元素的所有元素都是浮动的,因此在li 标记中添加clearfix 很重要,以免折叠成任何内容,您可以找到更多信息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;
      }
      

      如果有任何不清楚的地方,请随时问我任何问题。

      【讨论】:

        【解决方案6】:

        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>
        

        【讨论】:

          【解决方案7】:

          你可以用这个

           <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/

          【讨论】:

            【解决方案8】:

            为什么不用伪元素?

            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>

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

            【讨论】:

            • 如果图像后面有一个步骤,那就可以了,但是如果在第 3 步之后有另一个属于第 4 步和第 5 步的图像呢?
            • 嗨@Hobbes,我已经更新了示例以证明它也适用于超过 3 个项目。
            【解决方案9】:

            这很容易做到。当您使用 css 浮动属性时,您必须对其父元素使用溢出。在您的情况下:

            p.imagefloatright{
               overflow: auto;
            }
            

            必须解决问题。阅读更多关于https://www.w3schools.com/css/css_float.asp

            【讨论】:

              【解决方案10】:

              您可以在li 标签中使用after 伪元素来获取浮动元素的高度。此外,您必须指定您只想使用&gt; 选择器浮动 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>

              【讨论】:

                猜你喜欢
                • 2010-09-20
                • 1970-01-01
                • 2012-10-22
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多