skip to Main Content

I have a list comprised of 2 types of items, the items are always grouped, not mixed. Like:

a
a
a
b
b
b

How can I show a separator between the a items and the b items, a horizontal line. But how can I make that work even if some items have display: none.

For example:

a
a
a
(Show line here)
b
b
b
a
a
a
b [display: none]
(Show line here)
b
b
a
a
(Show line here)
a [display: none]
b
b
b

Is this possible with css only in a way that is not incredibly hacky?

For now I’m doing this manually with javascript.

Using border-top or border-bottom on first/last items is not a solution because when styled, the style touches the border, it looks off, I want the line to be completely separated. I guess a pseudo element, but not if it means using position: absolute hacks (unless it’s pretty simple).

What I do with javascript:

App.check_pinline = () => {
  App.remove_pinline()
  let last_pinned

  for (let item of App.get_items(`tabs`)) {
    if (!item.visible) {
      continue
    }

    if (item.pinned) {
      last_pinned = item
    }
    else {
      if (!last_pinned) {
        return
      }
      else {
        let pinline = DOM.create(`div`, `pinline`)
        last_pinned.element.after(pinline)
        return
      }
    }
  }
}

2

Answers


  1. use <hr> tag for making a breaking line

    Login or Signup to reply.
  2. This highly depends on the HTML structure that you have and how you hide the elements (you didn’t include it in your question, so this is just my assumption). I’d suggest just use ::after pseudo element on the last visible element of the same kind.

    If the display: none is from inline style:

    .a:not(:has(~ .a:not([style*='display: none']))):not([style*='display: none'])::after {
        content: '';
        height: 1px;
        background: black;
        width: 100%;
        display: block;
    }
    case 1
    <div>
      <div class="a">a</div>
      <div class="a">a</div>
      <div class="a">a</div>
      <div class="a">a</div>
      <div class="b">b</div>
      <div class="b">b</div>
      <div class="b">b</div>
      <div class="b">b</div>
    </div>
    <br>
    case 2
    <div>
      <div class="a">a</div>
      <div class="a">a</div>
      <div class="a">a</div>
      <div class="a">a</div>
      <div class="b" style="display: none;">b</div>
      <div class="b">b</div>
      <div class="b">b</div>
      <div class="b">b</div>
    </div>
    <br>
    case 3
    <div>
      <div class="a">a</div>
      <div class="a">a</div>
      <div class="a">a</div>
      <div class="a" style="display: none;">a</div>
      <div class="b">b</div>
      <div class="b">b</div>
      <div class="b">b</div>
      <div class="b">b</div>
    </div>

    The selector

    .a:not(:has(~ .a:not([style*='display: none']))):not([style*='display: none'])
    

    just means to select class a that has no next siblings with class a that has no style="display: none" and it also has no style="display: none" itself. If you hide the element with, for instance, .hidden class, then you can change the [style*='display: none'] with .hidden.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search