skip to Main 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;
}

2

Answers


  1. 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>
    Login or Signup to reply.
  2. Your idea is interesting, but currently, it cannot be achieved with CSS selectors alone.

    You might be looking for a selector named :has-slotted, but CSS is still evolving. There is a discussion on this topic on GitHub; you can visit this link: https://github.com/w3c/csswg-drafts/issues/6867 to check it out.

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