Search code examples
javascripthtmlcsscss-selectorssortablejs

Skip hidden element on :first-child selector


I'm using Sortable.js and I'm having the following problem:

I have a list of items that I want to sort, and I need the first element to be wider than all 3 others.

In order to do this, I have the following css:

#produto_img {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
      flex-wrap: wrap;
}

#produto_img > li {
  height: 100px;
  margin: 0 5px;
}

#produto_img > li:not(:first-child) {
  flex: 1;
}

#produto_img > li:first-child {
  width: 100%;
  height: 200px;
  margin-bottom: 10px;
}

It works fine when I start dragging any item after the first, even if I switch with the first item it works fine.

It creates the following markup:

First-markup

But when I start dragging from the first, I'll lose the styling because the plugin creates another item on its place and sets it to display: none, so the :first-child selector won't work anymore, and it loses the styling.

Second-markup

This gif shows what's happening.

enter image description here

My first tought would be to somehow skip the first-element if it is display: none, or use something like :first-child:visible, but this isn't working, obviously.

Is there any workaround?


Solution

  • Sadly the :visible pseudoclass is still distinct to jQuery. A workaround you can use though would be to handle the hiding by adding/removing a class.

    Then it's a matter of overrides

    li.hidden {
        display: none;
    }
    
    li:not(.hidden) {
        width: 100%;
        height: 200px;
        margin-bottom: 10px;
    }
    
    li:not(.hidden) ~ li {
        width: auto;
        height: auto;
        margin-bottom: 0;
        flex: 1;
    }