How to import stylesheet dynamically Polymer 2.0 - css

I want to import my stylesheet with variable inside :
<dom-module id="colors-palette">
<template>
<style>
:host {
--dark-gray: #263238;
--light-gray: #e6ebed;
--light-blue: #00bcd4;
--autovision-blue: #174291;
--background-box-number-applications: red;
--color-box-number-applications: orange;
}
</style>
</template>
</dom-module>
I want to do it dynamically. My folder structure is :
-themes
-theme1
-style.html
-theme2
-style.html
-theme3
-style.html
I detect the theme when my-app is ready and after that I try to import my style like this in the ready function :
Polymer.importHref(this.resolveUrl('../themes/' + this.getCurrentTheme() + '/colors-palette.html'));
The file is loaded but the var in the style in my-app.html doesn't change :
app-header {
background-color: var(--dark-gray);
}
And I've got this error in the console :
Could not find style data in module named colors-palette
Any idea ? Or maybe I have to do otherwise ?
Thanks a lot

Your colors-palette.html should just contain the styles setting it globally for html.
<custom-style>
<style is="custom-style">
html {
--dark-gray: #263238;
--light-gray: #e6ebed;
--light-blue: #00bcd4;
--autovision-blue: #174291;
--background-box-number-applications: red;
--color-box-number-applications: orange;
}
</style>
</custom-style>

Related

Pass a SASS variable to a Vue component property

I'm still very new to frontend development, and I'm working on a small Vue component that is basically a Vuetify card with a colored border on one side. The color is a property of the component. This works so far:
<template>
<v-card :style="borderColorStyle">
<slot></slot>
</v-card>
</template>
<script lang="ts">
import Vue, { PropType } from 'vue'
export default Vue.extend({
props: {
color: {
required: false,
type: String as PropType<string>,
default: null
}
},
computed: {
borderColorStyle () {
if (this.color) {
return `border-left: 5px solid ${this.color}`
} else {
return ''
}
}
}
})
</script>
<style lang="sass" scoped>
#import '#/sass/variables.sass'
.v-card
height: 100%
border-left: 5px solid $my__darkgray
</style>
As you can see, we use SASS, and we used it to define a number of colors.
Now, how can I use these SASS definitions to set the color when using this component?
For example, if my variables.sass contains
$my_coolgreen: #288970
is there any way I can do something like this?
<StatusCard color="my_coolgreen">
Some text
</StatusCard>
Via classes
While you can't pass a Sass variable through a prop to your styles in Vue 2, you could apply a CSS class that uses the Sass variable. For example, this template uses class binding to conditionally apply .myClass based on the value of color:
<template>
<v-card :class="{ myClass: color === '$my_coolgreen' }">
</v-card>
</template>
<style lang="scss" scoped>
#import '#/sass/variables.sass'
.myClass
border-left: 5px solid $my_coolgreen
</style>
Vue 3 <style vars>
Vue 3's <style vars> (still experimental) allows using props as CSS custom properties inside the style block, as shown in the example below. However, Vuetify 2 currently does not support Vue 3.
<style lang="scss" scoped vars="{ color }">
#import '#/sass/variables.sass'
.v-card
border-left: 5px solid var(--color)
</style>
Here is what we ended up doing:
<template>
<v-card :class="['pa-2','my__status__card', color]" style="background-color: white !important">
<slot></slot>
</v-card>
</template>
<script lang="ts">
import Vue, { PropType } from 'vue'
export default Vue.extend({
props: {
color: {
required: false,
type: String as PropType<string>,
default: 'info'
}
}
})
</script>
<style lang="sass">
.v-card
height: 100%
.my__status__card
border-style: solid !important
border-left-width: 5px !important
border-top-width: 0px !important
border-bottom-width: 0px !important
border-right-width: 0px !important
</style>
So we give the card a style that removes all borders except the left one.
The color property only works with theme colors. So this might not be a solution that makes sense for everyone, but it's what we needed.

Apply CSS Style inside ng-content

in an Angular application I have a component with <ng-content></ng-content>. I added the scss rules for content that will be put inside the ng-content, but they are ignored. I tried to solve using :host, but it doesn't work.
https://stackblitz.com/edit/angular-ewqhzj
Wrapper component:
<app-embed>
<p>Hello world!</p><h1 class="toBeColored">toBeColored</h1>
</app-embed>
Styles in embed component:
:host {
border: 5px solid red;
padding: 15px;
display: block;
.toBeColored {
color: pink;
}
}
The problem is that the pink color of 'toBeColored' string is not set
Try this
:host ::ng-deep{
border: 5px solid red;
padding: 15px;
display: block;
.toBeColored {
color: pink !important;
}
}
and remove encapsulation statement and try ti build
encapsulation: ViewEncapsulation.Native
Try adding encapsulation: ViewEncapsulation.Native to your embed component like
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
#Component({
selector: 'app-embed',
templateUrl: './embed.component.html',
styleUrls: ['./embed.component.scss'],
encapsulation: ViewEncapsulation.Native
})
export class EmbedComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
You can't achieve that with a clean way.
A workaround would be to create global css :
:host {
...;
::ng-deep .toBeColored {
color: pink;
}
}
But it will be deprecated. See this issue
::ng-deep is going to hold the web record for long-lived deprecated API.
You should be able to apply the styles in the parent component that projects the content into the ng-content tag. The angular styles isolation appears to consider the content to be part of the component where the HTML is declared.
https://stackblitz.com/edit/angular-ivy-q9dn68

CSS variables use in Vue

Is it possible to use pure CSS variables with Vue without having to link any stylesheets or use SASS/PostCSS? Unsure why I'm unable to get this to work in its most basic form.
<template>
<div id="test">
TEST
</div>
</template>
<style scoped>
:root {
--var-txt-color: #c1d32f;
}
#test {
color: var(--var-txt-color);
}
</style>
I know you highlighted "without having to link any stylesheet", but I run into the same issue and there is a simple option - use just one external css file and include it in your App.vue, then you can access the variables anywhere else, in scoped styles as well.
variables.css
:root {
--font-family: "Roboto", "Helvetica", "Arial", sans-serif;
--primary-color: #333a4b;
}
App.vue
<style>
#import './assets/styles/variables.css';
</style>
LandingView.vue
<style scoped>
#landing-view {
font-family: var(--font-family);
font-weight: 300;
line-height: 1.5em;
color: var(--primary-color);
}
</style>
This won't work as expected because of scoped attribute for stylesheet. Example above compiles into:
[data-v-4cc5a608]:root {
--var-txt-color: #f00;
}
And, as you understand, it will not target actual :root element.
It can be solved by:
Not using scoped attribute for this stylesheet. Notice that it may cause styles conflict with other variables declarations for :root element.
Using current component's wrapping element as root. If we declare variables this way:
.test {
--var-txt-color: #c1d32f;
color: var(--var-txt-color);
}
.test-child-node {
background-color: var(--var-txt-color);
}
Then it will can reuse variables for other elements of the same component. But still, it won't be possible to use declared variables inside child components without removing scoped, if it is the case.
Why not just use this?
<style scoped>
* {
--var-txt-color: #c1d32f;
}
</style>
The generated CSS is:
*[data-v-d235d782] {
--var-txt-color: #c1d32f;
}
This has been working for me.
I just discovered that it looks like this also works, using the "deep selector"
>>> {
--var-txt-color: #c1d32f;
}
Generated CSS is:
[data-v-d235d782] {
--var-txt-color: #c1d32f;
}
I think I like this method more.
One workaround is to define them under a non-scoped style element like the following. However one thing to note here is, these variables will be exposed to other Vue components as well.
<style>
:root {
--var-txt-color: #c1d32f;
}
</style>
<style scoped>
#test {
color: var(--var-txt-color);
}
</style>
Late answer - Here is a working example with css vars derived from standard vue structures.
<template>
<div>
<component :is="'style'">
:root {
--color: {{ color }};
--text-decoration: {{ textDecoration }};
--font-size: {{ fontSize }};
}
</component>
<p>example</p>
</div>
</template>
<script>
export default {
props:{
color: {
type: String,
default: '#990000'
}
},
data: function () {
return {
textDecoration: 'underline'
}
},
computed: {
fontSize: function (){
return Math.round(Math.random() * (5 - 1) + 1) + 'em';
}
}
}
</script>
<style>
p{
color: var(--color);
text-decoration: var(--text-decoration);
font-size: var(--font-size);
}
</style>
Starting from the top...
Vue must have 1 root element, so I needed a div tag in order to include a sample p tag. However, you can just use the component-is-style tag and get rid of the div and p tags. Note the need for extra quotations "'style'".
The normal vue style tag can be scoped or not - as needed.
Well, now you can use CSS variable injection.
<template>
<div>
<div class="text">hello</div>
</div>
</template>
<script>
export default {
data() {
return {
color: 'red',
font: {
weight: '800'
}
}
}
}
</script>
<style>
.text {
color: v-bind(color);
font-weight: v-bind('font.weight');
}
</style>
Those styles are also both reactive and scoped. There won't be any unintended inheritance issues. Vue manages the CSS variables for you.
You can take a look at the RFC here.

VUE component ignoring CSS

I have the following VUE component:
<template>
<div>
<div class="bottom-footer">
{{msg}}
</div>
</div>
</template>
<script>
export default {
name: 'LayoutFooter',
data () {
return {
msg: 'my test'
}
},
mounted () {
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.bottom-footer {
height: 200px;
background-color: #A7BFE8;
}
</scoped>
VUE is completely ignoring my scoped CSS. When page is rendered its simply not applied. There are no console errors. Ive tried removing the scoped attribute and its still ignored. Any ideas why VUE is doing this?
<style scoped>
.bottom-footer {
height: 200px;
background-color: #A7BFE8;
}
</style>
you need to close style

How do I declare embedded css with Binding.scala

I tried to declare some embedded css with Binding.scala
import com.thoughtworks.binding._, Binding._
import org.scalajs.dom._
#dom def css = <style>
body {
background-color: lightblue;
}
</style>
dom.render(document.head, css)
However, I got the error message:
ScalaFiddle.scala:6: error: not found: type lightblue
background-color: lightblue;
^
ScalaFiddle.scala:6: error: not found: value background
background-color: lightblue;
^
ScalaFiddle.scala:6: error: not found: value color
background-color: lightblue;
^
How can I fix it?
You see the error message because { is a special character in Scala's XML literal.
Use a CDATA section in the style element.
#dom def css = <style>
<![CDATA[
body {
background-color: lightblue;
}
]]>
</style>
The { does not have special meaning in the CDATA section any more.
Note this CDATA approach only works when coalescing flag is on.
See https://github.com/ThoughtWorksInc/Binding.scala/issues/30 and https://github.com/ThoughtWorksInc/Binding.scala/issues/58 if you accidentally turns the flag off.
Using the answer of Yang Bo:
#dom def css = <style>
<![CDATA[
body {
background-color: lightblue;
}
]]>
</style>
Gives me an Exception:
ScalaFiddle.scala:22: error: overloaded method value domBindingSeq with alternatives:
( text: String)binding.this.Binding.Constants[raw.this.Text]
...
See https://scalafiddle.io/sf/ATMVpjV/0
This solved it:
#dom def css = <style>
{"""
body {
background-color: lightblue;
}
"""
}
</style>
See https://scalafiddle.io/sf/ATMVpjV/1

Resources