SC5 / sc5-styleguide

Styleguide generator is a handy little tool that helps you generate good looking styleguides from stylesheets using KSS notation
http://styleguide.sc5.io/
MIT License
1.26k stars 171 forks source link

Shadow DOM encapsulation of patterns causes media query issues when viewing in Styleguide's interface #932

Open jaasum opened 8 years ago

jaasum commented 8 years ago

For simple patterns without any media queries the approach of encapsulating patterns as shadow DOM elements makes sense. However, if a pattern is responsive to the document via Media Queries issues are encountered. Using IFrames seems like a much better approach.

Example: Say I have a navigation bar I want to include in the pattern library. It has very different layouts between mobile devices, tablets, an desktop. If I am viewing the navigation bar in the styleguide on a desktop the pattern will respond to the width of the document not the width of its container, which is smaller and possibly within one of its breakpoints.

A workaround is to view each pattern in its own tab, but this is cumbersome and leads to some modules appearing broken outside of that view.

maximgatilin commented 8 years ago

+1

varya commented 8 years ago

Hi. Iframes have other drawback, and we cannot use them over ShadowDOM. Would it help if you disable the shadowDOM option with disableEncapsulation parameter, and write your custom processor to wrap every component with iframe? Check out for styleguideProcessors if the README to figure out how to make it. Also, the processors are mentioned in this post http://varya.me/en/posts/sc5-style-guide-next-level/

jaasum commented 8 years ago

I'm not sure that simply wrapping the components in an iframe tag is the right solution here. As far as I know iframes require a src attribute to an HTML document to render (you can't just wrap code in an iframe.) That HTML document will require all of the stylesheets, scripts, etc that the pattern needs to render.

Fundamentally the shadow DOM approach will not be compatible with media queries unless the width of the shadow DOM element exactly matches the width of the document (as it does when viewing in full screen.)

I'm not sure why iFrames wont work. The view you get when you render a pattern in full screen is what you want an iFrame to render. It would be as simple as:

 <iframe src="/section/2.8/fullscreen"></iframe>

There would need to be some scripts written to size the iframe to its contents so it renders nicely in the SC5 front end.

levito commented 8 years ago

First things first: +1 on this issue.

The better solution imho would be using srcdoc for the iframe content - there's also a polyfill for it: https://github.com/jugglinmike/srcdoc-polyfill

You would then simply put the shadow-dom markup into the srcdoc attribute of the iframe. This would mean there are no more requests than with shadow-dom encapsulation.

Now, you would need to auto-resize the iframes to the content. A possible solution for that is here: https://github.com/sinnerschrader/rubber-band

@varya, which other issues to you see with using iframes?

levito commented 8 years ago

@jaasum maybe we could get by with styleguideProcessors, as @varya suggested. As a proof of concept:

styleguideProcessors: {
    30: styleguide => {
        styleguide.sections.forEach(section => {
            if (typeof section.markup !== 'string') return;
            section.renderMarkup = `<iframe srcdoc='${section.markup}'></iframe>`;
        });
    }
}

You would have to add the styles at the beginning of the markup, and a script to resize the iframe, plus maybe some styling and a srcdoc polyfill for IE.

jaasum commented 8 years ago

There's another issue I noticed (closed via #953 which makes sense.)

When general scripts are included as part of extraHead they are run each time a component renders on a page. So if you had a script within your app that was designed to attach an event listener to an element, and you have that element with five states on a view then that script is going to get ran 5 times, which would potentially attach an event listener five times to a state. This means your event potentially will trigger a function five times.

Using iFrames means that any scripts as part of extraHead would only get ran once per the iFrame's document. This is a much closer approach to what the real application will be and allows less pattern-library specific code to check for attached event listeners, etc.

ullmark commented 6 years ago

Late addition to this ticket;

Other problems I've been having with the shadowdom version is;

I'm going to try out if I can make a iframe version work as suggested above.

ullmark commented 6 years ago

@levito I gave the srcdoc version a try and found following.

ullmark commented 6 years ago

So, I know this is an old ticket but If anyone is interested I was able to get it to work with an iframe using the following technique; https://gist.github.com/ullmark/36cdcb87ea7c2b771b2c36988aa41d56

note: I don't run my application's styles through "applyStyles" because since they are added to head, it would affect the styleguide. Instead I use the file created through my "regular" pipeline (entry; in the case of the gist).

Still a bit of a hack, but using this technique has solved a lot of issues for me with media queries, vw, vh, rem etc.