I'm trying to figure out how to apply the property cursor when using :host selector.
Others properties are correctly applied, but not cursor.
:host([disabled]) {
color: #626878;
background-color: #C0C4CB;
cursor: not-allowed!important;
}
:host refer to a web component made with LitElement.
Thanks for your help
Runs fine:
customElements.define("my-element", class extends HTMLElement {
connectedCallback() { // so attributes can be queried
this
.attachShadow({mode:"open"})
.innerHTML = `<style>
:host {
display: inline-block;
}
:host([disabled]) {
cursor: not-allowed !important;
background: pink !important;
color: grey !important;
}
</style>
<h1><my-element
${this.hasAttribute("disabled")?"disabled":""}></h1>`;
}
})
<style>
my-element{
cursor: pointer;
background: lightgreen;
color: green;
}
</style>
<my-element></my-element>
<my-element disabled></my-element>
Requires !important
From https://web.dev/shadowdom-v1/
One gotcha with :host is that rules in the parent page have higher
specificity than :host rules defined in the element. That is, outside
styles win. This allows users to override your top-level styling from
the outside. Also, :host only works in the context of a shadow root,
so you can't use it outside of shadow DOM.
Related
I've got a custom component <ui-title> that I wish to style differently based on what its direct parent element is.
For example, if it appears within <ui-section>, style it YELLOW. Within <ui-card> style it BLUE. If it appears anywhere else, style it GREEN.
Here's what I've tried:
:host {
background-color: green;
}
:host-context(ui-card) {
background-color: blue;
}
:host-context(ui-section) {
background-color: yellow;
}
This doesn't work because if an element is nested within both <ui-section> and <ui-card> because both sets of styles would be applied. I wish to apply a set of styles based strictly on the direct parent of the :host element.
Here's a StackBlitz that shows my issue.
I found that you can combine :host and ::ng-deep from this answer after few hours of searching and trying different combination of ::ng-deep, :host and :host-context.
https://stackblitz.com/edit/angular-ivy-yf1uff?file=src/app/ui-title/ui-title.component.css
So just moved the style related to the ui-card and ui-section to their own stylesheet and combine :host and ::ng-deep with child selector >
ui-card.component.css
:host > ::ng-deep ui-title {
font-size: 10px;
background-color: blue;
}
ui-section.component.css
:host > ::ng-deep ui-title {
background-color: yellow;
}
ui-title.component.css
:host {
display: block;
padding: 5px;
border-radius: 10px;
background-color: green;
}
I have a Nuxt 2 app and I'd like to create a component with a <style> tag like the following, using CSS properties for styling.
The goal is to define a default CSS property in the component that can be overridden from outside.
However, when I try this method, the default values don't seem to work at all.
<style lang="scss" scoped>
:root {
--default-badge-color: linear-gradient(90deg, #1717ff 0%, #bc29e0 92%);
--default-badge-text-color: #fff;
--default-badge-font-size: 1.6rem;
--default-badge-padding: 0.6rem 1rem;
--default-badge-border-radius: 16px;
}
.badge {
display: inline-flex;
align-items: center;
justify-content: center;
padding: var(--badge-padding, var(--default-badge-padding));
border-radius: var(--badge-border-radius, var(--default-badge-border-radius));
background: var(--badge-color, var(--default-badge-color));
color: var(--badge-text-color, var(--default-badge-text-color));
font-size: var(--badge-font-size, var(--default-badge-font-size));
text-align: center;
}
</style>
Do I have the wrong approach for the syntax?
EDIT: I corrected to padding: var(--badge-padding, var(--default-badge-padding)). But the CSS properties are still not found except I define them inside .badge.
It doesn't really make sense to scope :root, which is intended to select the root of the document with higher specificity than the html selector. That would be like scoping a style for <body>.
Perhaps you're hoping :root was a selector for the current component's root element (like :host is for Shadow DOM), but there's no such pseudo-class in Vue. An alternative is to apply your own class to the component's root element, and use that as a selector:
<template> 👇
<div class="my-root">
<div>...</div>
<div class="badge">...</div>
</div>
</template>
<style scoped>
👇
.my-root {
/* CSS custom properties */
}
.badge {
/* styles using the CSS custom properties above */
}
</style>
On the other hand, if you really are trying to add CSS custom properties to the document root from within <style scoped>, you can use the :global() pseudo-class function on :root:
<style scoped>
:global(:root) {
/* CSS custom properties */
}
.badge {
/* styles using the CSS custom properties above */
}
</style>
demo 1
Or a separate global <style> block just for :root:
<style>
:root {
/* CSS custom properties */
}
</style>
<style scoped>
.badge {
/* styles using the CSS custom properties above */
}
</style>
demo 2
How do I change the background color of Kendo Angular Grid row that is Selected? The following is not making the background color blue. Trying to figure out what is overriding it.
.k-grid .k-state-selected {
background-color: blue !important;
color: green;
}
.k-grid .k-alt.k-state-selected {
background-color: blue !important;
color: green;
}
Resources:
https://www.telerik.com/forums/changing-color-of-selected-row
Your styling doesn't affect the grid due to view encapsulation. You can read more about it here.
To force the use of your custom styling into a child component that has view encapsulation, which is set to Emulated by default for all components, add ::ng-deep before the CSS selector, like this:
:host ::ng-deep .k-grid .k-state-selected {
background-color: blue !important;
color: green;
}
:host ::ng-deep .k-grid .k-alt.k-state-selected {
background-color: blue !important;
color: green;
}
Since ::ng-deep convert the styling into a global rule, you need to add :host before it so that it will affect only the current component and its children.
Note that ::ng-deep is deprecated and technically shouldn't be used. A replacement is planned and ::ng-deep will probably be around until they come up with something else.
You can read more about ::ng-deep here.
The following code turns the button text a dark color when the button is selected. I assume this comes from code embedded in Bootstrap's btn class. How can I override the code to stop the text from changing color after the button is selected?
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<style>
.buttonColor{
color:#ff0000;
}
.buttonColor:hover{
color:#ffff00;
}
</style>
</head>
<body>
<button class="buttonColor btn" > Submit</button>
</body>
</html>
This is a common question: How to overwrite styling in Twitter Bootstrap, best way to override bootstrap css, the list goes on.
Read up on the CSS law of specifity. Essentially, if you're more specific in your class declaration, you can override others that are targeting the same elements:
In your example:
button.buttonColor.btn {
color: red;
padding: 50px;
}
Will override BootStrap's button.btn declaration.
Similarly, add pseudo selectors to override other states:
button.buttonColor.btn:active, button.buttonColor.btn:hover, etc
Assuming that by "selected" you mean the active state of a button, this is how you achieve it:
.buttonColor:active {
color: #ffff00;
}
Bootstrap uses both the :hover,:active and :focus pseudo-classes to target specific element states:
/* Example of Bootstrap :active styles for buttons */
.btn.active, .btn:active {
background-image: none;
outline: 0;
-webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,.125);
box-shadow: inset 0 3px 5px rgba(0,0,0,.125);
}
along with :
/* Example of Bootstrap :focus and :hover styles for buttons */
.btn.focus, .btn:focus, .btn:hover {
color: #333;
text-decoration: none;
}
So you'll just need to explicitly override them using your own style :
/* The more specific your selector (e.g. the more accurately it describes an */
/* element, the more likely a style will be applied. */
.btn.buttonColor:active,
.btn.buttonColor.active,
.btn.buttonColor:hover,
.btn.buttonColor:focus {
color: #ffff00!important;
}
or if you want to be more specific, you could explicitly target <button> elements exclusively :
button.btn.buttonColor:active,
button.btn.buttonColor.active,
button.btn.buttonColor:hover,
button.btn.buttonColor:focus {
color: #ffff00!important;
}
I have a custom element x-foo which I have defined a custom CSS property on to set the background-color called --xbg.
I use the element with elements of itself as children as so:
<x-foo class="outer">
Outer
<x-foo class="inner">
Inner 1
</x-foo>
</x-foo>
When I set --xbg on the outer, that value overrides the value of the inner element:
x-foo.outer {
--xbg: orange;
}
x-foo.outer x-foo {
--xbg: red;
/* Doesn't work, have to use !important?!?!*/
}
I've used the inspector in Chrome and can see that the child definition indeed is "lower" then the parent.
I have to "force" it to get higher with !important, which then has all sorts of other implications.
x-foo.outer x-foo {
--xbg: red !important;
/* Works */
}
Why is the child not overriding the parent property?
Here's a plunker for this with some more examples:
https://plnkr.co/edit/uZxg7G?p=preview (Only works in Chrome)
Simpler JSBin for other browsers:
http://jsbin.com/wuqobejeci/edit?html,output
the best way to solve this is to say the style only applies to the class contentwrapper from that host down
<style>
:host {
display: block;
}
:host > .contentwrapper {
padding: 1em;
background-color: var(--xbg, yellow);
}
</style>
Like that,
Here is a working Fiddle
The element has lower priority than the class. Try
x-foo.outer {
--xbg: orange;
}
x-foo.outer x-foo.inner {
--xbg: red;
}
Thought this was worth trying just based on Andrew's answer above -- just using the host style alone seems to work:
<style>
:host {
display: block;
padding: 1em;
background-color: var(--xbg, yellow);
}
</style>
https://jsfiddle.net/6tzoacxr/