Today, iframes are commonly used to assure separate scope and styling. Examples include Google’s map and YouTube videos.
However, iframes are designed to embed another full document within the current HTML document. This means accessing values in a given DOM element in an iframe from the parent document is a hassle by design. The DOM elements are in a completely separate context, so you need to traverse the iframe’s DOM to access the values you’re looking for. Contrast this with web components which offer an elegant way to expose a clean API for accessing the values of custom elements.
Imagine creating a page using a set of 5 iframes that each contain one component. Each component would need a separate URL to host the iframe’s content. The resulting markup would be littered with iframe tags, yielding markup with low semantic meaning that is also clunky to read and manage. In contrast, web components support declaring rich semantic tags for each component. These tags operate as first class citizens in HTML. This aids the reader (in other words, the maintenance developer).
In summary, while both iframes and the shadow DOM provide encapsulation, only the shadow DOM was designed for use with web components and thus avoids the excessive separation, setup overhead, and clunky markup that occurs with iframes.