How to override parent style when extending a polymer element - css

I have one element that extends another and I'm having trouble getting the styling to override the parent using the example in the documentation. For example, say I want to style the praise in the parent element:
<polymer-element name="polymer-cool">
<template>
<style>
:host #p {
color: red;
}
</style>
You are <span id='p'>{{praise}}</span> <content></content>!
</template>
...
</polymer-element>
but change that in an extension of that element:
<polymer-element name="polymer-cooler" extends="polymer-cool">
<template>
<!-- A shadow element render's the extended
element's shadow dom here. -->
<style>
#p {
color: blue;
}
</style>
<shadow></shadow> <!-- "You are cool Matt" -->
</template>
...
</polymer-element>
You can see in the JSfiddle below, that I haven't been able to change the color of the span#p. I've tried a few other things like
polymer-cooler #p {
color: blue;
}
And tried putting the style inside of the tags, but no luck. Hoping it's possible and I'm just missing something.
http://jsfiddle.net/jamstooks/tpyL9/

Well, this looks like this works. I'd love to get some clarification from someone on whether this is the best way to do this:
<polymer-element name="polymer-cooler" extends="polymer-cool">
<template>
<style>
{
:host::shadow #p
color: blue;
}
</style>
<shadow></shadow>
</template>
...
</polymer-element>
http://jsfiddle.net/jamstooks/tpyL9/4/
EDIT: 7/22/14
Per the comment from Scott below, I have updated the code above from :host /deep/ #p to :host::shadow #p

Related

Vue 3 slot styles from child component

Summary: I need to style the contents of a <slot>, from the child component. I'm using scoped css and the styles don't apply:
I have the following two components:
<!-- Parent.vue -->
<template>
<h1>{{ msg }} from Parent</h1>
<Child>
<h1>{{ msg }} from Child</h1>
</Child>
</template>
...
<style scoped>
h1 {
color: green;
}
</style>
<!-- Child.vue -->
<template>
<slot></slot>
</template>
...
<style scoped>
h1 {
color: red;
}
</style>
I want the 2nd <h1> to be red, but it's green, since the component is rendered with something like:
<h1 data-v-452d6c4c data-v-2dcc19c8-s>Hello from Child</h1>
<style>
h1[data-v-452d6c4c] {
color: green;
}
h1[data-v-2dcc19c8] {
color: red;
}
</style>
data-v-452d6c4c comes from Parent, and data-v-2dcc19c8-s from Child
If the second attribute, in the <h1> tag, was just data-v-2dcc19c8 the style I wanted would be applied, but since it has that -s suffix (slot?), it doesn't.
I could probably find some other solution with a class or something, but I rarely use <slot> and I want to understand the inner workings. That -s tells me that what I'm trying to do can be dealt with the help of the framework, what am I missing?
A working sample:
https://codesandbox.io/s/condescending-brown-ilfwn
Use the new :slotted selector in Vue 3:
Child.vue
<template>
<slot></slot>
</template>
<script>
export default {
name: "Child",
};
</script>
<style scoped>
:slotted(h1) {
color: red !important;
}
</style>
In Vue 3, child scoped styles don't affect slotted content by default.
In your particular example, the !important modifier is also necessary because the parent also defined an h1 style which would take precedence otherwise

Vue.js scoped css not working in single file component

I tried to set up a single file component. But the specified css (also scoped css) are ignored and not rendered.
I tried it with a simple component:
<template>
<div>
<h1>A Headline</h1>
<p>A test example</p>
</div>
</template>
<style scoped>
h1 {
color: red;
}
</style>
Component is rendered fine, except that the css style is not applied.
What am I doing wrong?
UPDATE: This answer was a solution to the question as originally posted. It no longer applies in light of the revised code example. I'll update this again when I have an answer to the question as it stands.
You are applying the style to the class .h1 but no element has this class. It seems likely you intended to apply the style to h1 elements, so remove the . from the name of your style definition:
<template>
<div>
<h1>A Headline</h1>
<p>A test example</p>
</div>
</template>
<style scoped>
h1 {
color: red;
}
</style>

#apply and a style dom-module won't work in Polymer 2.0

I'd like to make my styles dom-module, and because I like using the #apply css directive, I wish I could do something like :
<dom-module id="my-styles">
<template>
<style>
html {
--big-title: {
font-size: 1.3em;
text-transform: UPPERCASE;
}
}
</style>
</template>>
</dom-module>
But if I do that :
<dom-module id="my-element">
<template>
<style include="my-styles">
h1 {
#apply --big-title;
}
</style>
...
</template>
</dom-module>
Sadly this won't work. I am not sure why. My question is Can I use the #apply directive in conjunction with the styling dom-module solution ?
You should instead assign your properties to :host, I would say.
Check this example:
http://jsbin.com/dikacewulu/2/edit?html,output
Here, :host refers to the element including the style (so my-element). If you really wanted those rules to be available on html, you could use :root.

Polymer Styling Child Components

I am trying to style my child components. Isit wrong to put the style in a parent component? It appears that does not work.
I put the style for .card-page in the top level element (containing expenses-module where I use it)
<dom-module id="expenses-app">
<template>
<style>
...
.card-page {
display: block;
width: 100%;
}
</style>
<app-drawer-layout>
<app-header-layout>
...
<iron-pages selected="{{routeData.view}}" attr-for-selected="name">
<dashboard-module name="dashboard" route="{{subroute}}"></dashboard-module>
<expenses-module name="expenses" route="{{subroute}}"></expenses-module>
<settings-module name="settings" route="{{subroute}}"></settings-module>
</iron-pages>
</app-header-layout>
</app-drawer-layout>
</template>
In expenses module,
<paper-card heading="Expenses" class="card-page">...
</paper-card>
Seems like if I move the styles into expenses-module it works.
You cannot directly style elements inside custom element from their parents like that, because Polymer processes the style within <dom-module> and will apply styles only to direct child members. It will not descend into child custom elements.
In other words, standard CSS selectors will only work within the scope of the declaring component. Both in Shadow and Shady DOM.
For your styles to work with nested elements, you should use CSS mixins and properties. All PolymerElements and many 3rd party elements will come with such styling extension points. The naming usually follow the convention, where the main mixin is called same as the element itself. Additionally, there may be more specific mixins and properties, which style only parts of the element. <paper-card> docs for example lists --paper-card mixin, --paper-card-content mixin, --paper-card-header-color and more.
If you want to better control the styling of elements you use, you would want to create your own CSS mixins/properties and #apply() them to selected elements. See how in the example below --my-elem-card-page applies only to one of the two paper cards.
<!DOCTYPE html>
<html>
<head>
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import"/>
<link href="paper-card/paper-card.html" rel="import"/>
</head>
<body>
<my-wrapper></my-wrapper>
<dom-module id="my-elem">
<template>
<style>
.card-page {
#apply(--my-elem-card-page);
}
</style>
<paper-card heading="my-elem specific style" class="card-page">
<div class="card-content">
Content here
</div>
</paper-card>
<paper-card heading="Default style" class="unstyled-page">
<div class="card-content">
Content here
</div>
</paper-card>
</template>
</dom-module>
<dom-module id="my-wrapper">
<template>
<style>
# will be ignored
paper-card {
width: 200px;
}
my-elem{
--paper-card: {
color: blue;
display: block;
}
}
my-elem {
--my-elem-card-page: {
color: red;
}
}
</style>
<my-elem></my-elem>
</template>
</dom-module>
<script>
Polymer({
is: 'my-elem'
});
Polymer({
is: 'my-wrapper'
});
</script>
</body>
</html>

Polymer deep CSS

I am building a Polymer Single Page Interface with a lot of custom elements.
Now I want my elements to have some sort of master style, which I can define in the index.html or my main content element. Think of it like this:
index.html
<style>
.classWhichWillBeUsedInCustomElements {
mainColor: #e0e0e0;
}
</style>
or
<script>
mainColor = "#e0e0e0";
</script>
my-cool-element.html
<polymer-element name="my-cool-element">
<template>
<paper-button style="color: {{mainColor}}"></paper-button>
</template>
</polymer-element>
or
<polymer-element name="my-cool-element">
<template>
<style>
.coolButton {
width: 300px;
color: {{mainColor}};
}
</style>
<paper-button class="coolButton"></paper-button>
</template>
</polymer-element>
Except that this doesn't work.
I have tried:
Creating a global variable window.defaultColor and using it like color: {{defaultColor}};
Using core-style in a parent element, without much luck
Creating a css class in my index.html and calling it in a custom element
What is the right way to achieve this? I am trying to avoid using Less
Use the following pattern in the index.html or a global stylesheet:
<style>
body /deep/ .classWhichWillBeUsedInCustomElements {
mainColor: #e0e0e0;
}
</style>
Then you could use the class within the custom element. The global style will punch the shadow boundary. You could replace body with any other element or selector under which you want to punch the shadow dom boundary.
More on deep here: https://www.polymer-project.org/0.5/articles/styling-elements.html#cat

Resources