Styling `::slotted()` elements from the static styles property - css

I'm trying to style the :slotted elements in a component from the static styles property as recommended in the docs.
static get styles() {
return [
css `
::slotted(*) {
color: var(--white, #fff);
font-family: "Open Sans", sans-serif;
}
`,
// more styles...
]
}
But for some reason, is getting no effect.
Instead if define the same style in a style element into the render() function it works as expected
<style>
::slotted(*) {
color: var(--white, #fff);
font-family: "Open Sans", sans-serif;
}
// more styles...
</style>
I'm not sure if this is expected (and why) or if this is a bug.

Seems to be a syntax problem in my example. I was using an style array.
This is working fine
static get styles(): CSSResultArray {
return [
css`
:host {
/* styles */
}
::slotted(span) {
/* styles */
}
`,
css`
:host([data-type="primary"]) button {
/* styles */
}
`
];
}

Related

Lit-element not applying classes static get styles

I am making a simple component to test newest Lit-element a checkbox.
Upon testing static get styles only the first element I style is shown, I have seen in the documentation what I am trying should be correct, may I have some help?.
this is my component:
import {LitElement, html, css} from 'lit-element';
class CheckboxMJ extends LitElement {
static get properties(){
return{
check:{type:Boolean},
name:{type:String},
}
}
static get styles() {
return css`
.checkWrapper{
font-family: Roboto;
background-color: red;
font-weight: 500;
font-size:14px;
color:#283D3B;
border:none;
outline:none;
height: 150px;
width: 300px;
border-radius: 3px;
overflow:hidden;
padding:3px;
}
input[checkbox i]{
background-color:red;
}
`;
}
constructor(){
super();
this.check=false;
this.name="";
}
render() {
return html`
<div class="checkWrapper">
<input class="checkbox-mj" type="checkbox" name="${this.name}" value="${this.check}"> ${this.name}
</div>
`
}
}
customElements.define('checkbox-mj', CheckboxMJ);
I have been encountering this issue several times with other components, kept changing order, and names of classes until it worked but I feel so lost about how this should be done right, please somebody enlighten me on how to use this feature correctly.
You have to keep in mind that checkboxes are very difficult to stylize. Many properties simply have no effect on this input. On the other hand you have to use a standard css selector to stylize the checkbox input[type="checkbox"].
If you want the check property to be reflected in your checkbox you must do it this way:
?checked="${this.check}"
Look at this guides for more information https://lit-element.polymer-project.org/guide/templates (Bind properties to templated elements).
import {
LitElement,
html,
css
} from 'lit-element';
class CheckboxMJ extends LitElement {
static get properties() {
return {
check: {
type: Boolean
},
name: {
type: String
},
}
}
static get styles() {
return css `
.checkWrapper{
font-family: Roboto;
background-color: red;
font-weight: 500;
font-size:14px;
color:#283D3B;
border:none;
outline:none;
height: 150px;
width: 300px;
border-radius: 3px;
overflow:hidden;
padding:3px;
}
input[type="checkbox"]{
margin:1rem
}
`;
}
constructor() {
super();
this.check = true;
this.name = "Check";
}
render() {
return html `
<div class="checkWrapper">
<input class="checkbox-mj" type="checkbox" name="${this.name}" ?checked="${this.check}"> ${this.name}
</div>
`
}
}
customElements.define('checkbox-mj', CheckboxMJ);

Is there any way to make class names the same as the CSS custom variable?

I'm looking for any solution that can reduce this CSS redundancy:
--root {
--brown: #775E3E;
--headline: "Big Shoulders Display", "Oswald", "Open Sans", sans-serif;
}
.brown {color: var(--brown);}
.brown-bg {background-color: var(--brown);}
.headline {font-family: var(--headline);}
The end goal is using .headline and .brown classes directly in HTML.
<h1 class="headline brown">I AM BROWN WITH CUSTOM FONT</h1>
Can this be achieved without having to make an exhausting :root list of colors and then needing to specify each class name (which would be the same) individually?
Basically I want --headline = .headline & --brown = .brown
If there is no simple solution in CSS I am open to using SCSS, a SASS mixin or even javascript.
Thank you all in advance!
You can use SCSS for this. I built a snippet for you. It's self descriptive.
// Arrange them in
// varName: (type, value)
$vars: (
brown: (color, brown),
headline: (font-family, '"Big Shoulders Display", "Oswald", "Open Sans", sans-serif')
);
// Turn all those variables to CSS Variables
:root {
#each $var, $val in $vars {
--#{$var}: #{nth($val, 2)};
}
}
// Create classes out of those variables
#each $var, $val in $vars {
.#{$var} {
#{nth($val, 1)}: var(--#{$var});
}
// If type is color then generate a bg color class
#if nth($val, 1) == color {
.#{$var}-bg {
background-color: var(--#{$var});
}
}
}
Then it will generate CSS like this
:root {
--brown: brown;
--headline: "Big Shoulders Display", "Oswald", "Open Sans", sans-serif;
}
.brown {
color: var(--brown);
}
.brown-bg {
background-color: var(--brown);
}
.headline {
font-family: var(--headline);
}
This is probably what you're looking for. Happy helping.

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.

How to use #apply in a react component with css modules

I've got this in a global style.css:
:root {
--font: {
font-family: "Source Sans Pro", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
}
... and this in a react component's style.css:
.rightnav {
#apply --font;
float: right;
color: white;
}
In the component itself:
import React from "react"
import cssModules from "react-css-modules"
import style from "./style.css"
render() {
return (
<ul>
<li className={style.rightnav}>Blog</li>
</ul>
)
}
I get an error: No custom properties set declared for font.
You've got to import the global stylesheet into the local one. Because postcss-apply has no way to know about that global file while parsing the local one. So it's a good idea to have a partial with only custom properties and custom property sets declarations.
You probably want something like postcss-import
#import 'path/to/variables.css';
.rightnav {
#apply --font;
float: right;
color: white;
}

Flex 4.5 embedding font not working for tabbars and list items

I am trying to embed a custom font to all elements of my mobile app.
Only the Action Bar and Buttons are changed meanwhile the Tabbars and ListItems doesn't change.
Here's my style.css code
/* CSS file */
#namespace s "library://ns.adobe.com/flex/spark";
/* StyleableTextField, regular */
#font-face {
src: url("assets/fonts/Roboto-Light.ttf");
fontFamily: "robotoLight";
fontWeight: bold;
embedAsCFF: false;
}
/* Label, regular */
#font-face {
src: url("assets/fonts/Roboto-Light.ttf");
fontFamily: "robotoLightCFF";
fontWeight: normal;
embedAsCFF: true;
}
s|Label {fontFamily: "robotoLightCFF";}
s|ActionBar {fontFamily: "robotoLight";}
s|LabelItemRenderer {fontFamily: "robotoLight";}
s|Button {fontFamily: "robotoLight";}
s|TabbedViewNavigator #tabBar {fontFamily: "robotoLight";}
s|TextInput {fontFamily: "robotoLight";}
s|View {fontFamily: "robotoLight";}
global
{
text-align: left;
content-background-color: #FFFFFF;
content-background-alpha: 0.59;
fontFamily: "robotoLight";
}
/** this is the bar the top of the app **/
s|ActionBar{
chromeColor:#4D99E0; /* more like background color */
titleAlign:center;
textShadowAlpha: 0;
}
/* This is the styling of the tabbed navigator */
s|TabbedViewNavigator #tabBar {
chromeColor: #4D99E0; /* color of background on buttons */
color: #ffffff; /* color of text on tab names */
}
.playButton,.pauseButton,.resumeButton,.initButton {
chromeColor: #4D99E0;
color: #fff;
}
And here's a screenshot of how it appears:
screenshot http://samzkingdom.com/wp-content/uploads/2014/01/Capture.png
How do I do this? Or what am I doing wrong?
[EDIT]
It is totally my mistake that I just tested on the emulator on my Desktop. It works perfectly on the Android device.
Try this for tab navigator. Just replace the font family okay..
.tabNavigator
{
font-family: "Helvetica Neue";
font-weight:normal;
horizontal-gap:1;
tab-style-name:"myTabs";
corner-radius:0;
selected-tab-text-style-name: "myselectedTabs";
border-color:#D6D6D6;
}
.myTabs
{
font-size:13;
font-family: "Helvetica Neue";
font-weight:normal;
fill-colors:"#e5e5e5","#f6f6f6";
fill-alphas:1,1;
color:#000000;
corner-radius:0;
text-selected-color:#000000;
text-roll-over-color:#000000;
border-color:#D6D6D6;
}
.myselectedTabs
{
font-size:13;
font-family: "Helvetica Neue";
font-weight:normal;
fill-colors:"#FFFFFF","#FFFFFF";
fill-alphas:1,1;
color:#0d7dbd;
corner-radius:0;
text-selected-color:#0d7dbd;
text-roll-over-color:#0d7dbd;
}
For StyleableTextField (used in many UI elements in mobile Flex, for example in ListItemRenderer) you should use embedAsCFF: false; as explained in Adobe's blog Embedding Fonts in Flex Mobile Projects
For example the following works for me (for the Lists):
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
s|ActionBar {
chromeColor: #0066CC;
color: #FFFFFF;
titleAlign: center;
/* textShadowAlpha: 0; */
textShadowColor: #000000;
}
#font-face {
src: url("/assets/fonts/arial.ttf");
fontFamily: embFont;
embedAsCFF: false; /* required for StyleableTextField */
unicodeRange:
U+0020-U+0040, /* Punctuation, Numbers */
U+2660-U+2666, /* Card suits */
U+0041-U+005A, /* Upper-Case A-Z */
U+0061-U+007A, /* Lower-Case a-z */
U+0410-U+0451; /* Cyrillic */
}
s|LabelItemRenderer {
fontFamily: embFont;
}

Resources