Styling Not Applied to Vue Web Component During Development

Building Vue app with target Web Component - SCSS styling not applied?

I'm not sure why, but a workaround is to import the SCSS within the <style> block instead of <script>:

<style lang="scss">
@import '~@/assets/main.scss';
</style>

Vuetify build as Web component style not showing

What is the problem?

When vue-cli is building a webcomponent it ignores main.js and uses entry-wc.js instead as the official doc says: When building a Webcomponent or Library, the entry point is not main.js, but an entry-wc.js file....

By default vue-cli already has this entry file, and it uses src/App.vue as the entry component which means that if you importing vuetify into App.vue all vuetify's components won't be rendered there, they will be rendered 1 level below (all your components that being imported into App.vue).

Solution 1

Remove all vuetify's components from App.vue and move them 1 level lower.

<template>
<HelloWorld/> <!-- v-app / v-main / v-btn go inside HelloWorld -->
</template>

<script>
import vuetify from '@/plugins/vuetify'
import HelloWorld from './components/HelloWorld';

export default {
name: 'App',
vuetify,
components: {
HelloWorld,
},
};
</script>

<style>
@import 'https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css';
</style>

Solution 2

Leave vuetify's components inside App.vue (remove import vuetify... + <style> @Import...).

Create a 'wrapping' component (e.g. Wrap.vue), import vuetify and its styles into this component, and import App.vue.
Add to the CLI command the new component name:

...
"wcin": "vue-cli-service build --target wc --inline-vue --name my-element 'src/Wrap.vue'"
...

Why does my vuetify app lose its styling when I turn it into a web component?

Veutify add the CSS styling to the top of the document when you use any of its components. So when your component gets wrapped inside a custom element within Shadow DOM, then all the styling provided by Veutify is not accessible inside shadow DOM.

There are two options you can try:

  1. Use custom elements without shadow DOM
  2. Try to inject Veutify inside shadow DOM using constructible stylesheets.

How to build web component with styling library using vite and vue 3?

Using custom elements without Shadow DOM is trivial. Just add like the way you do traditionally. However, with Shadow DOM, things are tricky. Only inheritable CSS styles pass through the Shadow DOM. Everything else is blocked. No straight forward integration with existing design systems (Vuetify, Ant, etc.) is not directly possible if that library is only exposing global CSS.

If the design system or a component library is exposing styles i.e. css files for individual components, then you can that with some effort.

The best solution is to use constructable stylesheet. You can use a bundler like Webpack to load the stylesheet for individual component (if and only if it is provided) as a string and feed it to the stylesheet constructor method as illustrated here.

// Read SCSS file as a raw CSS text using Webpack/Rollup/Parcel
import styleText from './my-component.scss';

const sheet = new CSSStyleSheet();sheet.replaceSync(styleText);

// Use the sheet inside the web component constructor
shadowRoot.adoptedStyleSheets = [sheet];

However, Firefox and Safari are yet to implement it.

If you need a fallback, then there are ways that are not so clean. Approach is same. Import the CSS/SCSS as a string and using the template literal, add it to the element's inner style tag.

import styleText from 'ant/button.css';

class FancyComponent extends HTMLElement {

constructor() {
super();

const shadowRoot = this.attachShadow({ mode: 'open' });

shadowRoot.innerHTML = `
<!-- Styles are scoped -->
<style>
${styleText}
</style>
<div>
<p>Hello World</p>
</div>
`;
}
}

customElements.define('fancy-comp', FacyComponent);

This all relies on the assumption that ant/material/veutify is exposing styles as individual files instead of one global file.

Alternately, the browsers have started supporting the link tag inside the Shadow DOM. But again it is really useful if you have styles for individual components. Read more about that here.



Related Topics



Leave a reply



Submit