Search code examples
javascripthtmlcss

How to add display:none to parent element of a slot with no content


I'm using web component(s) and I have created a Panel class.
By default if no content has been provided for a named slot then the parent should not be visible

<div class="panel-header">
    <slot name="header">
        Header
    </slot>
</div>
<div class="panel-body">
    <slot name="body">
        Body
    </slot>
</div>
<div class="panel-footer"> <!-- display:none -->
    <slot name="footer"></slot> <!-- if there's no content -->
</div>

Here's my parent component's render method:

render() {
    this.innerHTML = `
        <panel-component>
            <span slot="header">Member Info</span>
            <span slot="body">${this.search ? this.search : 'Please select a member'}</span>
            <!-- no footer slot -->
        </panel-component>
    `;
}

I'd prefer to apply this style via CSS but I'm open to suggestions with JavaScript

::slotted(div:empty) {
    display: none;
}

.panel-footer:empty,
.panel-footer:has(:empty) {
    display: none;
}

:scope > :empty {
    display: none;
}

::slotted(div[slot="footer"]:empty) {
    display: none;
}

It does not appear that there is a CSS solution but based on the suggestions below I was able to get the desired result

render() {
        this.shadowRoot.appendChild(template.content.cloneNode(true));
        const parent = this.shadowRoot.querySelector(".panel-footer");
        const footer = this.shadowRoot.querySelector("#footer");
        footer.assignedNodes().length > 0 ? parent.style.display = "block" : parent.style.display = "none";
    }

Solution

  • You can achieve that with help of JS. So first you need to add some id or class to the element on which you want to check if it contains any content or not. In below example I have added id checkContent to slot.

    After that you need js to check if checkContent contains any content or not. If it contains then panel-footer should be displayed or else it should be hidden.

    Codepen for same is here. If I have misunderstood or missed something then please share.

    function hideContent(){
      let panelFooter = document.querySelector('.panel-footer');
      let content = document.getElementById('checkContent')
      
      if(content.innerHTML == null || content.innerHTML == ''){
        panelFooter.style.display = "none";
      }
      else{
        panelFooter.style.display = "block";
      }
      
      console.log(panelFooter.style.display)
    }
    
    hideContent()
    <div class="panel-footer"> 
        <slot name="footer" id="checkContent">Remove this text and check console.</slot>
    </div>