CSS float: как сохранить float рядом с текстом, которому он принадлежит? - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть процедура, которая состоит из шагов. Некоторые шаги сопровождаются изображением.

    <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

В прошлом я достиг желаемого результата в XSL-FO, вставляя блок ширины с высотой = 0 перед каждым плавающим изображением.

Можно ли получить желаемый макет с помощью команд CSS? Или мне нужно вставить блок в HTML, прежде чем применить CSS к HTML?

Ответы [ 10 ]

0 голосов
/ 14 сентября 2018

Вы можете использовать псевдоэлемент 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>
0 голосов
/ 12 сентября 2018

Это очень легко сделать. Когда вы используете свойство css float, вы должны использовать переполнение с его родительским элементом. В вашей ситуации:

p.imagefloatright{
   overflow: auto;
}

должен исправить проблему. Подробнее о https://www.w3schools.com/css/css_float.asp

0 голосов
/ 12 сентября 2018

Решение 1: Использование Flex

Я бы порекомендовал использовать flex и justify-content: space-between. Единственным недостатком его использования было бы, если вы поддерживаете более старые браузеры, такие как IE10 - тогда вы можете проверить https://caniuse.com/#search=flex для получения дополнительной информации.

Что касается space-between, то просто, как согласно MDN

Элементы равномерно распределены внутри контейнера выравнивания вдоль главной оси. Интервал между каждой парой соседних предметов одинаков. Первый элемент находится на одном уровне с основным краем, а последний элемент находится на одном уровне с основным краем.

Это означает, что первый дочерний элемент будет выровнен по началу родительского элемента, а последний дочерний элемент выровнен по концу, а оставшееся пространство будет разделено поровну между остальными дочерними элементами, если они существуют, что даст вам желаемую разметку если img всегда последний ребенок, независимо от того, сколько существует детей div.

Лично я бы обнаружил, что использование flex - это самый удобный и один из самых чистых способов «позиционировать» и «размещать» различные элементы на странице.

Вы можете найти код ниже и рабочую скрипку здесь

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, чтобы не свернуться ни к чему, вы можете найти дополнительную информацию здесь .

Так что ваш код хотел бы это, и вы можете найти рабочую скрипку здесь

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 голосов
/ 07 сентября 2018

Вот простой способ использования 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>
0 голосов
/ 12 сентября 2018

Для очистки поплавка, который содержит динамическое содержимое, т.е. Изображение может иметь динамическую высоту, вам нужно очистить сам родительский элемент.

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

Вот демоверсия .

0 голосов
/ 07 сентября 2018

Вы можете использовать это

 <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 голосов
/ 07 сентября 2018

Почему не с псевдоэлементом?

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 голосов
/ 07 сентября 2018

Если на каждом шаге с изображением будет только одно изображение, и , изображение не будет доступно более чем на один шаг, вы можете написать селектор, чтобы иметь После очистите каждое плавающее изображение, но оно очень жесткое:

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>

Если между шагами и изображениями нет строгой связи 1: 1, вам необходимо стратегически применить свойство clear к определенным шагам.

0 голосов
/ 07 сентября 2018

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 голосов
/ 07 сентября 2018

Вы должны использовать свойство clear не для элемента p, но создать другой элемент в том месте, где вы хотите остановить 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>

Кстати, вот фрагмент кода, показывающий лучшую компоновку ваших шагов (с моей точки зрения), что более логично, каждый шаг - это блок с изображением и текстом, расположенными правильно.

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...