Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS floats: how to keep the float near the text it belongs to?

I've got a procedure that consists of steps. Some steps are accompanied by an image.

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

and my CSS:

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

This is the default output. Images don't stay with the steps they belong to, the text for step 2 is put alongside image 1:

enter image description here

I want the image that belongs to step 2 to be vertically aligned with step 2:

enter image description here

In the past, I've achieved my desired result in XSL-FO by inserting a full-width block with height =0 before each floated image.

Can I achieve my desired layout using CSS commands? Or do I need to insert a block in the HTML before I apply the CSS to the HTML?

like image 885
Hobbes Avatar asked Sep 04 '18 12:09

Hobbes


Video Answer


2 Answers

To clear the float which contains the dynamic content ie. image can have dynamic height, you'll need to clear the parent element itself.

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

It means that you need to use clear on the element which contains the floating elements.


For brevity, I would rename it like:

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

Here's a demo.

like image 85
Bhojendra Rauniyar Avatar answered Oct 29 '22 00:10

Bhojendra Rauniyar


You should use clear property not on p element, but create another element in the place where you would like to stop float.

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>

By the way, here is a code snippet showing a better layout for your steps (from my point of view), which is more logical, each step is a block with image and text positioned correctly.

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>

If you still would like to have text in a separate p element you may have all steps as a div elements with properly styled paragraph and images inside. I am also applying display:inline-block on p element to prevent it from taking whole width. You can do same or use span instead of 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>
like image 34
Artem Arkhipov Avatar answered Oct 28 '22 23:10

Artem Arkhipov