A button unaffected by external CSS styles


This is a demo / proof of concept built for my blog post How to create a web button unaffected by external CSS styles on my programming blog. You can read the post for more info.


Example

The HTML code behind it is simple.

<button>This is a regular button</button>

It's red because the CSS styles below are having their way with it!

button {
    color: #fff;
    font-size: 20px !important;
    background-color: red !important;
}

This is also a regular buton, but it was generated by a sample inline widget code.

This is how the sample inline widget code looks like.

(function (wrapper_id) {
    var wrapper = document.getElementById(wrapper_id);

    var button = document.createElement('button');
    button.innerText = 'Dynamically generated regular button';
    button.onclick = function () {
        alert('I was clicked!');
    }

    wrapper.appendChild(button);
})('unique_id')

The next button is the same dynamically generated button, but now the CSS style can't reach it, since it's safely tucked inside the Shadow DOM.

It was built with the following JavaScript code

(function (wrapper_id) {
                
    var wrapper = document.getElementById(wrapper_id);

    var shadow_wrapper = wrapper.attachShadow({
        mode: 'open'
    });

    var button = document.createElement('button');
    button.innerText = 'Dynamically generated regular button';
    button.onclick = function () {
        alert('I was clicked!');
    }

    shadow_wrapper.appendChild(button);

})('shadow-button-wrapper');

This final button does not use a div but it's a true custom component.

This is a custom regular button

The HTML code looks like this

<regular-button>This is a custom regular button</regular-button>

It was built with the following JavaScript code

(function () {
    
// Create a class for the element
class RegularButton extends HTMLElement {
    constructor() {
        // Always call super first in constructor
        super();

        // Create a shadow root
        const shadow = this.attachShadow({
            mode: 'open'
        });

        // Create a button node and the existing content to it
        const button = document.createElement('button');
        button.textContent = this.innerHTML;

        // Append it to the shadow root
        shadow.appendChild(button);
    }
}

// Define the new element
customElements.define('regular-button', RegularButton, {
});

})();

Not clear? Read the full blog post: How to create a web button unaffected by external CSS styles