CoryG CoryG - 2 months ago 10
CSS Question

Override Only Some Items via list-style

I'm trying to override the bullets in a hierarchical arrangement of ordered and unordered lists in HTML nested arbitrarily deep, but only for some items. The nesting portion of this problem is important because browsers will assign different bullets to lists based on the depth of the list, so using a static override for items that are not checked/unchecked/etc is not an option.

I've put together a JSFiddle outlining this issue and the code is below in case JSFiddle is unavailable. In the fiddle the items named "noncheck" should have the default bullet styles.

HTML:

<ul>
<li>
<div><div class="checkbox"></div>unchecked</div>
</li>
<li>
<div><div class="checked"></div>noncheck</div>
</li>
<li>
<div><div class="checked"></div>noncheck</div>
</li>
<li>
<div><div class="checkbox"><div class="check"></div></div>checked</div>
</li>
<li>
<div><div class="checkbox"></div>unchecked</div>
</li>
<li>
<div><div class="checkbox"></div>unchecked</div>
</li>
<li>
<div><div class="checkbox"><div class="check"></div></div>checked</div>
</li>
<li>
<div><div class="checkbox"><div class="x"></div></div>x</div>
</li>
<li>
<div><div class="checkbox"><div class="x"></div></div>x</div>
</li>
<li>
<div><div class="checkbox"><div class="x"></div></div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</li>
<li>
<div><div class="checkbox"><div class="x2"></div></div>x</div>
</li>
<li>
<div><div class="checkbox"><div class="x2"></div></div>x</div>
</li>
<li>
<div><div class="checkbox"><div class="x2"></div></div>x</div>
</li>
<li>
<ul>
<li>
<div><div class="checkbox"></div>unchecked</div>
</li>
<li>
<div><div class="checked"></div>noncheck</div>
</li>
<li>
<div><div class="checked"></div>noncheck</div>
</li>
<li>
<div><div class="checkbox"><div class="check"></div></div>checked</div>
</li>
<li>
<div><div class="checkbox"></div>unchecked</div>
</li>
<li>
<div><div class="checkbox"></div>unchecked</div>
</li>
<li>
<div><div class="checkbox"><div class="check"></div></div>checked</div>
</li>
<li>
<div><div class="checkbox"><div class="x"></div></div>x</div>
</li>
<li>
<div><div class="checkbox"><div class="x"></div></div>x</div>
</li>
<li>
<div><div class="checkbox"><div class="x"></div></div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</li>
<li>
<div><div class="checkbox"><div class="x2"></div></div>x</div>
</li>
<li>
<div><div class="checkbox"><div class="x2"></div></div>x</div>
</li>
<li>
<div><div class="checkbox"><div class="x2"></div></div>x</div>
</li>
<li>
<div><div class="checked"></div>noncheck</div>
</li>
</ul>
</li>
<li>
<div><div class="checked"></div>noncheck</div>
</li>
</ul>


CSS:

ul {
list-style: none;
margin-left: 0;
padding-left: 19px;
}
li {
text-indent: -19px;
position: relative;
left: 38px;
margin-right: 38px;
}
.checkbox {
border: 1px solid black;
width: 11px;
height: 11px;
display: inline-block;
margin-right: 5px;
margin-top: 2px;
margin-bottom: -1px;
position: relative;
top: 1px;
}
.checkbox > .check {
border: 0px;
margin: -11px 0px 0px 18px;
padding: 0px;
display: block;
font-size: 20px;
}
.checkbox > .check:before {
content: '✔';
color: #000000;
}
.checkbox > .x {
border: 0px;
margin: -3px 0px 0px 19px;
padding: 0px 0px 0px 0px;
display: block;
font-size: 13px;
position: relative;
top: -1px;
}
.checkbox > .x:before {
content: '✖';
color: #000000;
}
.checkbox > .x2 {
border: 0px;
margin: -6px 0px 0px 18px;
padding: 0px 0px 0px 0px;
display: block;
font-size: 16px;
}
.checkbox > .x2:before {
content: '✕';
color: #000000;
}

Answer

If you want those list items which contain divs with class "checkbox" to have no bullets, and the list items that don't, to behave normally, the most straightforward solution should have been a CSS selector for "li that contains div.checkbox". Unfortunately, CSS doesn't allow that.

One possible solution is to programmatically assign assign classes to the list items that should have their bullets suppressed.

Since the HTML is created server side on your end, setting those classes shouldn't be too hard.
In the below example, I simulate the same with Javascript (since StackSnippets don't have a server side). Note that this leaves the original HTML unchanged; but this is just for demonstration purposes.
I also changed the CSS a bit, since you don't want to suppress the bullets on all li elements, just the ones the checkbox appears in.

var items = document.getElementsByTagName('li');
for (var i = 0; i < items.length; ++i)
  if (items[i].children.length && items[i].children[0].className == 'checkbox')
    items[i].setAttribute('class', 'checkitem');
ul.checklist {
}
ul.checklist > li {
    margin-left: 0px;
    padding-left: 0px;
}
ul.checklist > li.checkitem {
    margin-left: -40px;
    padding-left: 2px;
    text-indent: -18px;
    position: relative;
    left: 38px;
    margin-right: 37px;
    list-style: none;
}
ul.checklist > li.checkitem > div.checkbox {
    border: 1px solid black;
    width: 11px;
    height: 11px;
    display: inline-block;
    margin-right: 5px;
    margin-top: 2px;
    margin-bottom: -1px;
    position: relative;
    top: 1px;
}
ul.checklist > li.checkitem > div.checkbox > div.check {
    border: 0px;
    margin: -11px 0px 0px 17px;
    padding: 0px;
    display: block;
    font-size: 20px;
}
ul.checklist > li.checkitem > div.checkbox > div.check:before {
    content: '✔';
    color: #000000;
}
ul.checklist > li.checkitem > div.checkbox > div.x {
    border: 0px;
    margin: -3px 0px 0px 18px;
    padding: 0px 0px 0px 0px;
    display: block;
    font-size: 13px;
    position: relative;
    top: -1px;
}
ul.checklist > li.checkitem > div.checkbox > div.x:before {
    content: '✖';
    color: #000000;
}
ul.checklist > li.checkitem > div.checkbox > div.x2 {
    border: 0px;
    margin: -6px 0px 0px 17px;
    padding: 0px 0px 0px 0px;
    display: block;
    font-size: 16px;
}
ul.checklist > li.checkitem > div.checkbox > div.x2:before {
    content: '✕';
    color: #000000;
}
<ul>
  <li>
    root node example
  </li>
</ul>

<ul class="checklist">
  <li>
    <div class="checkbox"></div>unchecked
  </li>
  <li>
    <div class="checked"></div>noncheck
  </li>
  <li>
    <div class="checked"></div>noncheck
  </li>
  <li>
    <div class="checkbox">
      <div class="check"></div>
    </div>checked
  </li>
  <li>
    <div class="checkbox"></div>unchecked
  </li>
  <li>
    <div class="checkbox"></div>unchecked
  </li>
  <li>
    <div class="checkbox">
      <div class="check"></div>
    </div>checked
  </li>
  <li>
    <div class="checkbox">
      <div class="x"></div>
    </div>x
  </li>
  <li>
    <div class="checkbox">
      <div class="x"></div>
    </div>x
  </li>
  <li>
    <div class="checkbox">
      <div class="x"></div>
    </div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </li>
  <li>
    <div class="checkbox">
      <div class="x2"></div>
    </div>x2
  </li>
  <li>
    <div class="checkbox">
      <div class="x2"></div>
    </div>x2
  </li>
  <li>
    <div class="checkbox">
      <div class="x2"></div>
    </div>x2
  </li>
  <li>
    <ul>
      <li>
        <div class="checkbox"></div>unchecked
      </li>
      <li>
        <div class="checked"></div>noncheck
      </li>
      <li>
        <div class="checked"></div>noncheck
      </li>
      <li>
        <div class="checkbox">
          <div class="check"></div>
        </div>checked
      </li>
      <li>
        <div class="checkbox"></div>unchecked
      </li>
      <li>
        <div class="checkbox"></div>unchecked
      </li>
      <li>
        <div class="checkbox">
          <div class="check"></div>
        </div>checked
      </li>
      <li>
        <div class="checkbox">
          <div class="x"></div>
        </div>x
      </li>
      <li>
        <div class="checkbox">
          <div class="x"></div>
        </div>x
      </li>
      <li>
        <div class="checkbox">
          <div class="x"></div>
        </div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </li>
      <li>
        <div class="checkbox">
          <div class="x2"></div>
        </div>x2
      </li>
      <li>
        <div class="checkbox">
          <div class="x2"></div>
        </div>x2
      </li>
      <li>
        <div class="checkbox">
          <div class="x2"></div>
        </div>x2
      </li>
      <li>
        <div class="checked"></div>noncheck
      </li>
    </ul>
  </li>
  <li>
    <div class="checked"></div>noncheck
  </li>
</ul>