Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I style ul/ols to be able to flexibly wrap around float-ed content?

I have what I feel like should be a relatively straightforward set of constraints that I can't seem to find a solution to. I'm trying to build a set of WYSIWYG component stylings that will work flexibly together, and can't get a combination of bulleted/numbered lists to wrap predictably around float-ed figures without losing indentation or causing overlapping content:

Restrictions:

  • Nested lists should be indented more with each level of nesting
  • Floating content can float either to right or left side
  • Lists can be arbitrarily long and should wrap predictably around floating content

This is the default styling for a list to the right of content that has "float: left" set. The bullets overlap with the floating content and the indentation is lost.

.pull-left {
  background: #3333ff;
  color: white;
  float: left;
  width: 50%;
  height: 80px;
}
<div class="pull-left">Floating content</div>

<ul>
  <li>First Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item</li>
    </ul>
  </li>
  <li>Second Item</li>
  <li>Third Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item</li>
    </ul>
  </li>
</ul>

Setting a value to overflow (i.e. overflow: hidden) on the <ul> element fixes the bullet formatting + the indentation, but doesn't allow the content to wrap:

.pull-left {
  background: #3333ff;
  color: white;
  float: left;
  width: 50%;
  height: 80px;
}

ul {
  overflow: hidden;
}
<div class="pull-left">Floating content</div>

<ul>
  <li>First Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item</li>
    </ul>
  </li>
  <li>Second Item</li>
  <li>Third Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item</li>
    </ul>
  </li>
</ul>

The only other solution I can think of is to use nested transforms and offset padding to get it to work:

.pull-left {
  background: #3333ff;
  color: white;
  float: left;
  width: 50%;
  height: 80px;
}

ul {
  padding: 0;
}

li {
  list-style-position: inside;
  transform: translateX(30px);
  padding-right: 30px;
}
<div class="pull-left">Floating content</div>

<ul>
  <li>First Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item</li>
    </ul>
  </li>
  <li>Second Item</li>
  <li>Third Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item</li>
    </ul>
  </li>
</ul>

However, this solution doesn't work when the floating content is floating to the right:

.pull-right {
  background: #3333ff;
  color: white;
  float: right;
  width: 50%;
  height: 80px;
}

ul {
  padding: 0;
}

li {
  list-style-position: inside;
  transform: translateX(30px);
  padding-right: 30px;
}
<div class="pull-right">Floating content</div>

<ul>
  <li>First Item
    <ul>
      <li>Nested Item with long enough text that it overlaps the floating content</li>
      <li>Nested Item</li>
    </ul>
  </li>
  <li>Second Item</li>
  <li>Third Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item</li>
    </ul>
  </li>
</ul>

I've scoured the internet for a flexible solution to this and can't find anything anywhere. Is this set of (pretty reasonable) restrictions just not something that can be done? Or am I missing something?

like image 260
Daniel Thompson Avatar asked Sep 26 '18 01:09

Daniel Thompson


1 Answers

I think you were close with the transform solution but you can probably change it to use text-indent and adjust indentation for each level.

.pull-left {
  background: #3333ff;
  color: white;
  float: left;
  width: 50%;
  height: 80px;
}

ul {
  padding: 0;
}

li {
  list-style-position: inside;
  text-indent: 10px;
  padding-right: 30px;
}

ul ul>li {
  text-indent: 20px;
}

ul ul ul>li {
  text-indent: 30px;
}

ul ul ul ul>li {
  text-indent: 40px;
}
<div class="pull-left">Floating content</div>

<ul>
  <li>First Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item
        <ul>
          <li>Nested Item</li>
          <li>Nested Item</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Second Item</li>
  <li>Third Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item</li>
    </ul>
  </li>
</ul>

It will also be fine with right floating:

.pull-right {
  background: #3333ff;
  color: white;
  float: right;
  width: 50%;
  height: 80px;
}

ul {
  padding: 0;
}

li {
  list-style-position: inside;
  text-indent: 10px;
  padding-right: 30px;
}

ul ul>li {
  text-indent: 20px;
}

ul ul ul>li {
  text-indent: 30px;
}

ul ul ul ul>li {
  text-indent: 40px;
}
<div class="pull-right">Floating content</div>

<ul>
  <li>First Item
    <ul>
      <li>Nested Item long long long long long long long long long text</li>
      <li>Nested Item
        <ul>
          <li>Nested Item with long long long long long long long long long text</li>
          <li>Nested Item</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Second Item</li>
  <li>Third Item
    <ul>
      <li>Nested Item</li>
      <li>Nested Item</li>
    </ul>
  </li>
</ul>
like image 179
Temani Afif Avatar answered Nov 01 '22 06:11

Temani Afif