Обновлено 12 декабря 2015. Спустя три года после написания этого поста в голову пришло более простое и стабильное решение.
Для дефолтных браузерных стилей характерно такое поведение: если картинка обтекает список слева, маркеры списка налазят на картинку. От этого можно избавиться незначительно переписав стили.
Эту проблему можно решить, но придется переписать все отступы для тегов ul
, ol
и li
. Так как ul > li
могут использоваться не только для текста с маркерами, но и для менюшек, слайдеров, списков новостей и других семантических конструкций, задавать стили напрямую тегам ol
, ul
и li
опасно. Иначе в дальнейшем придется слишком часто эти стили обнулять. Поэтому создадим отдельный класс .textlist
, чтобы ставить его на наши ul
и ol
.
.textlist {
margin: 0;
padding: 0;
}
.textlist > li {
margin: 0;
padding-left: 2em;
list-style-position: inside;
text-indent:-1em;
overflow: hidden;
}
overflow: hidden
тут нам нужен для того, чтобы запретить тексту обтекание картинки по строкам внутри li
. Теперь каждая li
обтекает картинку как прямоугольный блок.
list-style-position: inside
чтобы втянуть маркер списка внутрь блока.
А всё остальное, чтобы отступы выглядели как раньше.
Новое решение
Обновлено 11 июня 2017. Пофикшен баг с наплывом маркеров на картинку при первой загрузке или когда выключен кэш.
Для списков, у которых нет классов, перенесём дефолтный отступ 2.5em с левого края на правый, а сами li
сдвинем на те же 2.5em вправо при помощи transform: translateX(2.5em)
.
ul:not([class]),
ol:not([class]) {
padding-left: 0;
padding-right: 2.5em;
}
ul:not([class]) li,
ol:not([class]) li {
transform: translateX(2.5em);
animation: fixlists 1s;
}
@keyframes fixlists {
0% {
text-indent: -0.001em;
}
100% {
text-indent: 0;
}
}
Списки, не имеющие класса, мы выбираем, чтобы не повредить меню, слайдеры и прочие конструкции, которые используют ul li
в своей структуре. Подробнее про это в посте про селектор :not().
В отличие от старого решения, элементы списка обтекают картинку естественным образом, не оставляя зазоров под картинкой.
Чтобы починить баг в Хроме, Опере и других браузерах на движке Blink, пришлось добавить невидимую анимацию. Она заставляет браузер пересчитать размеры элементов списка и поставить маркеры на место.
Живой пример: