In the case of web components, there is a fundamental problem that makes widgets built out of HTML and JavaScript hard to use.
Problem: The DOM tree inside a widget isn’t encapsulated from the rest of the page. This lack of encapsulation means your document stylesheet might accidentally apply to parts inside the widget; your JavaScript might accidentally modify parts inside the widget; your IDs might overlap with IDs inside the widget and so on.
Shadow DOM addresses the DOM tree encapsulation problem.
For example, if you had markup like this:
<button>Hello, world!</button>
<script>
var host = document.querySelector('button');
var root = host.createShadowRoot();
root.textContent = 'こんにちは、影の世界!';
</script>
then instead of
Hello, world!
your page looks like
こんにちは、影の世界!
Not only that, if JavaScript on the page asks what the button’s textContent is, it isn’t going to get “こんにちは、影の世界!”
, but “Hello, world!”
because the DOM subtree under the shadow root is encapsulated.
NOTE: I have picked up above content from https://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/ as it helped me understand shadow DOM a little better than answers already here. I have added relevant content here so that it helps others but do take a look at the link for detailed discussion on same.