sveltejs / svelte

web development for the rest of us
https://svelte.dev
MIT License
79.49k stars 4.2k forks source link

Restriction of one top level style block causing issues #5110

Open gavinmcfarland opened 4 years ago

gavinmcfarland commented 4 years ago

Is your feature request related to a problem? Please describe. I've created a tool which preprocesses HTML and scans class names for functional CSS. This CSS is then translated into styles using CSS variables which are inserted into the HTML using style blocks. A unique class name is also added to the element so the styles are tied to the element.

This is problematic in Svelte however, because it requires there to be only one style block. I'm aware there have been some discussions on this before but I can't remember what the outcome was and if it's intended to only support one top-level style block.

Describe the solution you'd like Ideally, I think you should be able to use more than one style block. This is what native HTML supports and I would expect to be able to drop a style block anywhere and for it to still work. I think in this case, the error handling is doing more harm than good. In the case of this preprocessor, there isn't any need for Svelte to be able to support the style blocks it adds, other than just passing it to the browser. This error is intended to make Svelte users aware that only the top-level style block will be supported but then denies the ability to process the file because more than one style block exists in the source code.

Alternatively, an easier way to solve this using a preprocessor would also be welcomed. Like the ability to traverse preprocessor content source code easier.

Describe alternatives you've considered I've tried to create a workaround for this by combining all the style blocks created by my preprocessor and applying them as one style block but it's not easy and I encounter quite a challenges.

The first is I need to convert the content provided by the svelte.preprocess API into something that's easier to work with. Then I search for all the style tags, merge their contents together and prepend it to the beginning of the document.

But in converting the content from a string to a syntax tree using a library like Cheerio it causes some issues converting back to a string, for example, it escapes some symbols like ampersands.

I also have the additional burden that the library I'm using to implement my tool has a conflict with some Svelte syntax, so for now, I can't use pHTML on every component.

This is the progress I've made so far for combining all style blocks into one through a preprocessor.

markup({ content, filename }) {
        // Need to implement way code fence pHTML for now because of syntax issue
    return phtmlUtilityClass.process(content, { from: filename }).then(result => {

        let $ = cheerio.load(result.html)

        styleBlocks.push($('style').html())
        var styleTag = $('style')
        styleTag.remove()

        $('body').prepend(`<style>${styleBlocks.join('')}</style>`)

        let newHTML = $('body').html()

        return { code: newHTML, map: null }
    });
}

How important is this feature to you? Fairly important, it's blocking me from integrating my CSS framework into Svelte. But I'm likely to be in the minority for use cases. I use style blocks for live previewing of styles in some projects so I'm not looking forward to coming up against this issue there also.

I'm open to any other alternatives for how I could work around this.

Additional context You can view a work in progress of the project I'm trying to create. https://github.com/limitlessloop/phtml-utility-class/tree/version-3

Just referencing this issue where multiple style blocks were also being discussed. https://github.com/sveltejs/svelte/issues/2762

gavinmcfarland commented 4 years ago

After playing around I've realised I can avoid this issue if I wrap my style blocks in a div or span. This should work for most cases and to be safe I can apply a style of display="none" to the wrapper spans.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.