-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vue stripping out styles from inline SVG #11697
Comments
While putting a The warning was introduced because it was common for users to fall for this. It's still possible for users to ignore the warning and explicitly inject |
It's not possible when using svg files directly. |
How are you using SVG files directly as inline SVG? |
Using this config: // vue.config.js
module.exports = {
devServer: {
overlay: false
},
chainWebpack: (config) => {
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
svgRule
.use('vue-loader')
.loader('vue-loader-v16')
.end()
.use('vue-svg-loader')
.loader('vue-svg-loader')
}
} |
You can use raw-loader to import the SVG file as a string and then use it in |
Sure, that would be a solution 👍 How about adding an optional rule to vue-loader regarding style preservation from svg files? Would the team be firmly against it? I could make a PR. Coming from a react and vue background I tend to use as much svg files as I can as they are lighter than pngs. |
@MeisterTea I agree 100% it would be awesome to not have to think when we use SVGs in our apps. Using styles tags in SVG represents a significant risk of conflict. Depending on where your SVG files come from, you might have the option of exporting them with attributes instead of |
I would really like to see better support for SVGs in the Vue ecosystem. I struggled with issues (like style tags getting stripped) when implementing our icon system at work. I implemented @posva The main issue with this solution is that not all styles can be inlined. You can't do anything with pseudo selectors or at-rules (media queries, feature detection). This means that implementing an icon system with interactive svgs becomes very difficult. You can pull out the svg into a SVGO is also available as a webpack loader so I think implementing this inside of vue-cli could be doable and alleviate the namespacing concerns |
My comment is only accounting for what was said initially: allowing If there is a webpack loader involved, it will be the loader's job to automate any process to avoid inlining style. It could be extracting the styles to a separate CSS file, inlining styles, wrapping the svg with props to change styles. All of this is way beyond Vue's scope and should live in the loader itself. I think with the upcoming css vars mode in SFC, there is a lot of room for improvement for loaders to simplify working with svgs and Vue |
Inlining styles are not always possible. Eg. things like |
Thanks for the response. I only care about this issue being acknowledged as a real one and re-opened -- not to imply any scheduling or priority.
@posva I was trying to address your concern RE: namespace risk, so I brought up SVGO + loaders.
You mentioned that the loader can handle this. I agree, this is a good stop-gap. However, if loaders are the final solution, we will diverge from the SVG spec, but only in SFC-compiled components... not template-compiled ones. Keeping template-compiled markup equivalent to Vue SFCs seems like it would be a requirement. @Justineo I think a webpack-loader approach is possible and an OK near-term solution for many users. Using the Again, I would love this feature to be in the core Vue compiler due to the template-compilation issue outlined above. We seem to be interested in diversifying our build stack from Webpack so if we choose a loader-based solution, this issue may become more apparent as time goes on. Vue just shouldn't strip style tags in SVG. It's against spec, we should figure out a solution |
Joining in here because I also want to handle this a little better. I'm using Mermaid, which generates these |
It would be very nice to have options. Stripping styles or preserving them. Also vue could try to make styles scoped if user wants. |
https://github.com/jpkleemans/vite-svg-loader It also uses SVGO, which extracts the classes in the <style> tag into inline styles. By default it did not strip classes which are used more than once, as it increases output size. But it's needed to be able to apply the styles, because Vue strips the style tag away. Thats why I needed to set the svgLoader({
svgo: true,
svgoConfig: {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
inlineStyles: {
onlyMatchedOnce: false,
},
},
},
},
],
},
}) |
Version
2.6.11
Reproduction link
https://jsbin.com/lurayuxofo/edit?html,js,console,output
Steps to reproduce
What is expected?
SVG to be styled according to the style element
What is actually happening?
Vue is giving a warning "[Vue warn]: Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <style>. " and also stripping the style element so the SVG is appearing with no style.
I am opening the exact same issue as this one because it's been ignored and this should be fixed by now.
It's been plaguing vue since 2016.
The fix so far:
In the meantime, this can be fixed by adding this attribute
xmlns:svg="http://www.w3.org/2000/svg"
to your<svg>
tag and writing your style as this :<svg:style type="text/css">
The text was updated successfully, but these errors were encountered: