Use of Pseudo-Elements in Polymer.js - javascript

I'm taking my first steps with Polymer.js, and I'm struggling with creating a pseudo-element.
This is what I tried:
In my host document:
<style type="text/css">
#host::x-a-cool-test {
color: green;
}
</style>
<div id="host">
<my-custom-element></my-custom-element>
</div>
In my custom element:
<element name="my-custom-element">
<template>
<style>
#host {
* { display: block; color: blue; }
}
</style>
<div id="group" pseudo="x-a-cool-test">
just some text
</div>
</template>
<script>
Polymer.register(this);
</script>
</element>
That will show just my text in blue. That is correct, because according to this, rules wrapped in a #host have higher specificity than any selector in the parent page.
My question:
If I delete color: blue from inside the #host block in my template, the text is shown in black and NOT green as I would expect. Why is that???

I believe this plunker works how you want it to. Basically, the CSS pseudo-element has to be applied directly to the custom element (in this case the my-custom-element). I switched id="host" to it (instead of its parent div) and the code worked.
<div>
<my-custom-element id="host"></my-custom-element>
</div>
Note: The overriding nature of #host may change. Some (myself included) think it should be more for providing default, fallback styles. In this case rules in the host document will override #host rules instead of the other way around.

Related

How to changing a style in node_modules in its own vue <style> tags

I want to make changes to the css file inside the multiselect package. But I don't want to change it from within node_modules, all I want is to write it between style tags of my page that I created with vue. I want to change the white-space property But I can't see any change when I write as below. Can you help with this?
Default.css (Node_modules)
.multiselect-tag {
align-items: center;
background: var(--ms-tag-bg,#10b981);
border-radius: var(--ms-tag-radius,4px);
color: var(--ms-tag-color,#fff);
white-space: nowrap;
}
My template
<template>
<div class="filters">
<Multiselect
class="multiselect"
v-model="value"
mode="tags"
placeholder="Customer"
:close-on-select="false"
:filter-results="false"
/>
</div>
</template>
My CSS code
<style scoped>
.multiselect {
--ms-tag-bg: #dbeafe;
--ms-tag-color: #2563eb;
--ms-radius: 0.475rem;
--ms-dropdown-radius: 0.475rem;
--ms-spinner-color: #2563eb;
--ms-tag-ml: 0.85rem;
}
.multiselect,
.multiselect-tag {
white-space: normal !important;
}
</style>
I think you need to remove the scoped from your <style scoped> style tag, as this will let the styles only apply for the current component (and the root node of the child). But you want to style an element the Multiselect component.
<style>
.multiselect {
--ms-tag-bg: #dbeafe;
--ms-tag-color: #2563eb;
--ms-radius: 0.475rem;
--ms-dropdown-radius: 0.475rem;
--ms-spinner-color: #2563eb;
--ms-tag-ml: 0.85rem;
}
.multiselect,
.multiselect-tag {
white-space: normal !important;
}
</style>
Beware that removing the scoped will make the styles apply globally, so all Multiselect instances will be affected. If this is not what you need, you might try to use deep selectors.
See vue style docs.
Hope this helps.
So if I have got you right, you want to change / overwrite your default CSS from your stylesheet with new values in your hmtl.
To do this, simply insert "style" within your tag.
For example:
<Multiselect class="multiselect" style="color: black;"/>

My q-btn elements are not rendering appropriately in Quasar

I am new to Quasar and I don't know why, but my q-btn component buttons render as white backgrounds sometimes, ignoring the background-color I added to them, using external stylesheets.
The following are examples of this baffling problem
The above button should look like below
Another example is
The above one should look like
The buttons render properly some times, but just like that, without any clear pattern, they render with the white backgrounds.
It was suggested that the reason this was happening is because the buttons are being rendered before the external scss files are parsed. I changed the style of importing external scss files from
<template>
...
</template>
<script>
import './_custom-style.scss // initial import style
...
</script>
to
<template>
...
</template>
<script>
...
</script>
<style lang="scss" src="./_custom-style.scss"></style> // new css import style
This didn't work.
It was suggested that I use q-btn's color prop, (which is less than ideal, because I won't be able to use a custom hex color for my background), however I tried adding the color prop to it, using one of quasar's colors (in the color palette) and it still isn't rendering appropriately all the time. I don't know what else to do.
EDIT:
These are the scss file and one of the templates that use the q-btn component.
airtime {
...
&__redeem-btn {
margin-top: 1rem;
width: 80%;
padding: .5rem;
background-color: $purple-dark-3;
color: $primary-white;
font-size: 1.7rem;
}
}
<template>
<div class="airtime text-center">
<h1 class="..">Congratulations!</h1>
<p class="..">You got <strong>7</strong> questions correct</p>
<q-img
src="icons/...svg"
transition="fade"
class=".."
alt=".."
/>
<p class=".."></p>
<q-btn
class="airtime__redeem-btn"
rounded
label="Redeem"
no-caps
#click="$emit('selectNetworkProvider')"
/>
</div>
</template>
I have discovered the error. It turns out that there was a clashing style in my application
.q-btn__wrapper {
background-color: $primary-white;
}
This style overrode the background-color of the q-btn components.

Learning JS - why do my elements not have any styles

I'm struggling with my web page
document.getElementById("btn").addEventListener("click", function(){
var g = document.getElementById("guitar");
console.log("Styles:", g.style.left,g.style.top, g.style.width,g.style.height, g.style.background);
});
<html>
<head>
<style>
.stage {
position:relative; width:400px;height:300px;background:brown;
}
.guitar {
position:absolute; left:20px; top:10px; width:150px; height:150px; background:#f63f63;
}
</style>
</head>
<body>
<input type="button" id="btn" value="Do something" />
<div class="stage" id="stage">
<div class="guitar" id="guitar" />
</div>
<body>
</html>
If you note the last line of code, I'm referring to the g for the guitar (I know bad naming etc, I'm just messing about here).
The question I have is, when I put a watch on g and expand the properties and navigate to style, there are none (there are no values in the list of styles). Even the background shows an empty value, yet the HTML is rendering it correctly.
Why can't I see the values in the watch Window?
Your g element doesn't have any style attributes...
You can see all of the style definitions on the 'computed style', as they are regular css declarations, and NOT defined via attributes.
Try window.getComputedStyle(g,null).getPropertyValue("height");
This should do the trick
From https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style:
The HTMLElement.style property returns a CSSStyleDeclaration object that represents only the element's inline style attribute, ignoring any applied style rules.
This means that if you have an element <div style="left: 10px;">, then its style object will contain the left value, but not if you only have a CSS rule div { left: 10px; }.
As already stated you can use getComputedStyle() to get the actual style applied by CSS.

Polymer CSS ::content selector not working

I haven't used Polymer since version 0.5 so I decided to give it a shot again. I've been having some trouble with the :host and ::content selectors, especially given I found that the :host selector only works when my style tag is placed outside the tag.
Anyway, my problem is that I cannot get the host selector to work unless I specify display: block in my CSS under :host. Second, apparently there isn't a difference between the selectors ":host" and ":host ::content". I'm trying to ONLY style content which is inserted into the content tag without using a wrapper element.
Here is my code from custom-element.html:
<dom-module id="custom-element">
<style>
/* Demonstrating how to specify inserted content
any content added here is styled
*/
:host ::content
{
color: green;
}
/* This CSS targets the custom-element tag itself */
:host
{
padding: 4px;
background-color: gray;
}
</style>
<template>
<!-- Title will be placed here before the content -->
<h2 id="title">{{title}}</h2>
<!-- Any content inside the tag will be placed here -->
<content></content>
</template>
....
And here is the relevant location where it is used in index.html:
<!-- Auto-binding templates -->
<template id="t" is="dom-bind">
<h1>Your input was <span>{{inputValue}}</span></h1>
<br>
<input is="iron-input" bind-value="{{inputValue}}">
<input type="button" value="Add to list" onClick="pushItem()">
<ul>
<!-- Repeating templates -->
<!-- Here, the items attribute specifies the array of items to bind to. -->
<template id="repeatingList" is="dom-repeat" items="{{listItems}}">
<!-- This demonstrates that we can find the index and data for every item in the specified array -->
<li>Array index <span>{{index}}</span>- <span>{{item}}</span></li>
</template>
</ul>
<br>
<custom-element title="{{inputValue}}"><p>Lorem ipsum!</p></custom-element>
</template>
Here's how it appears (the gray background doesn't appear behind the element content and the color should only be applied to the content tag): https://goo.gl/photos/p2EjTSjySCh2srY78
From https://www.polymer-project.org/1.0/docs/devguide/styling.html#styling-distributed-children-content
You must have a selector to the left of the ::content pseudo-element
Your shadow DOM styles should be inside your <template> tag.
::content doesn't directly map to an element and so styles applied directly to it will be ignored. Instead it allows you to override styles inside the content.
So:
:host { background-color: gray; } /* Styles <custom-element> */
:host ::content { color: green; } /* Does nothing */
:host ::content > p { color: green; } /* Overrides the <p>Lorem ipsum!</p> to be green */
Finally note that <custom-element> has no default styles at all of its own - it only has what you specify in :host. For any visual components you'll find that you just about always need to specify display in the :host.

Styling content inserted in the Shadow DOM

I have this example:
http://codepen.io/dbugger/pen/IuDxw
Where I have an insertion point inside the Shadow DOM and I try to apply an style to it, making it disappear. But the image is still visible. I suspect there is some principle I haven't undestood propely from the Web Components.
Can someone explain me what am I doing wrong?
The trick is that the image is not, as kkemple mentioned, part of the Shadow DOM, but rather the Light DOM, which means it's not directly accessible from inside the component. It's user provided content, like the parameters passed into a class constructor in an OOP language. If at all possible, then, the user should provide their own styles to go with it.
That being said, there are definitely valid use cases where the component author wants to style user-provided content. Hiding certain parts of the user-provided markup based on attributes on the host, events (clicks), etc. is definitely one of those. In that case, wrap the <content> element in a Shadow DOM element and hide that:
<template>
<style>
.image {
display: none;
}
</style>
<div class="image">
<content></content>
</div>
</template>
http://codepen.io/anon/pen/rCGqD
On a side note: It is technically possible to apply styles directly to Light DOM elements, but be aware that in many cases this is considered leaking implementation details to the outside world. If the first solution works, use that instead.
It is not working is because your code is not in the shadow DOM, the div and image is still accessible through default styling. I forked your codepen and added the styling so you could see.
var host = document.querySelector(".host");
var template = document.getElementById( 'template' );
var root = host.webkitCreateShadowRoot();
root.appendChild( template.content );
<template id="template">
<style>
.wrapper {
display: none;
}
</style>
<div class="wrapper">
<content selector=".img"></content>
</div>
<h2>In the Shadows</h2>
</template>
<style>
img {
border: 1px solid black;
}
</style>
<div class="host">
<img class="img" src="http://placehold.it/200x275&text=1" alt="" />
</div>
http://codepen.io/kkemple/pen/euBKs
I didn't go in to why it was not creating a shadow DOM element as your JS looked correct to me but here is a great article on shadow DOM web-ponents:
http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/

Categories