Nuxt CSS properties declared on :root selector are not found - css

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

Related

Scoped css class with elements

I use vue with vuetify. I have to use sass to override the style of vuetify components.
With the following code I want to update the style of my text field.
<style scoped lang="scss">
.center {
input {
text-align: center;
}
}
</style>
Without the scope attribute it works. But how do I make it work and only apply the current component?
<v-text-field v-model="myText" class="center" #input="onTextInput" />
Thanks
For Vue2 you need to add ::v-deep before the class.
Ex:
::v-deep .target-class {
background-color: #000;
}
For Vue3
:deep(.target-class) {
background-color: #000;
}

CSS property 'cursor' not working with :host selector

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.

Hide input field from vuejs-datepicker

I am using vuejs-datepicker in one of my vue project. I want to hide the default input and show the Calendar when user press a button. I am trying to have the <datepicker/> inside a div apply css for the div so that I can hide it.
<div class="datePickerDiv">
<datepicker class="date" ref="datepick"></datepicker>
</div>
<style scoped>
.datePickerDiv {
position: relative;
float: left;
margin-top: -40px;
}
.datePickerDiv input {
border: none;
background: transparent;
}
</style>
But its not working as I expect. Sample https://codesandbox.io/s/relaxed-sea-qfuix?file=/src/components/HelloWorld.vue:742-910
You need to use the >>> combinator in order to deeply select the input tag:
.datePickerDiv >>> input {
border: none;
background: transparent;
}
This is because you're using the scoped attribute on your style tag. scoped will only work to apply styling to child components directly referenced in your current Vue component. In this case, datepicker is creating its own child input which will not be affected by the style, unless you use the deep selector shown above.
For applying style in your date picker tag, use input-class instead of only class. The styling does not work on the default scoped style tags, so add another style tag beneath your scoped style tag like follows:
<style scoped>
---your scoped Styles ----
</style>
<style >
-- Apply your unscoped style over vue date picker here ---
</style>
Example
<datepicker input-class="date" ref="datepick"></datepicker>
<style>
.date {
display: none !important;
}
</style>
Add prop input-class with class hide-input. This will apply the hide-input class to the input element. Read more about props here.
<datepicker input-class="hide-input"></datepicker>
.hide-input{
display: none !important;
}

How to style :root based on Custom Element Attribute

Update: See: How to style :root without !important using proper specificity
Is it not possible?
This Style rule is totally ignored
You forgot the parenthesis to :host():
elem.attachShadow({mode: 'open'})
.innerHTML = `
<style>
:host([player="X"]) {
display: inline-block;
background: red;
padding 1em;
}
</style>
Hello World`
<game-toes id=elem player="X"></game-toes>

How do I override bootstrap?

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;
}

Resources