Conditional styles, hover and ReactJS - css

I have an anchor within a <div>, the anchor uses conditional styling for it's background and this seems make it so that the a:hover style gets discarded. Actually it doesn't matter if I have conditional or just a fixed color, if I remove the background-style from component.js the hover-effect from style.css kicks in.
My question is how do I achieve the hover effect while still having a conditional background-color?
component.js:
<div>
<a href="#"
style={{
background: (day === 2) && "#f1f1f1"
}} />
</div>
style.css:
div a {
display: block;
}
div a:hover {
background: blue;
}

This is a great use case for CSS stylesheet vs inline styles which will override due to css specificity.
Pop a class on it and do something like.
.conditional {
background-color: #f1f1f1;
}
.conditional:hover {
background-color: red;
}

Just to add, take a look at styled components https://www.styled-components.com/ . Its a matter of preference but using the style object can be a bit limiting and difficult to read (IMHO), some would say styled components is hard to read - your choice
There's lots more to styled components so definitely worth taking a look.
your use case would be something like below (or you could have your styled component in a different module)
import React from 'react'
import styled from 'styled-components'
const Link = styled.a`
display: block;
& :hover {
background: ${props => props.dayValue === 2 ? white : blue};
}
`
render(){
return (<div> <Link href='' dayValue={this.props.dayValue}/></div>)
}

One solution would be to use !important to force the :hover behaviour even when inline styles as you have are applied, like so:
div a:hover {
background: blue !important;
}
If dynamic inline styling is not required (ie you don't need a dynamic background color), then you'll typically want to avoid the use of !important in favour of class based styling:
JSX
<div>
<a href="#" className={ (day === 2) && "dayTwoClass" } />
</div>
CSS
div a {
display: block;
}
// Increased specificity of div to a causes blue background on hover
div a:hover {
background: blue;
}
// Lesser specificity causes f1f1f1 background when not hovered
.dayTwoClass {
background: #f1f1f1;
}

Related

Style children of shadow dom ::part element

I have a web component that renders the following in the shadow dom:
<custom-banner>
#shadow-root
<div part="headertext">
I am the header text!
</div>
...
</custom-banner>
To style the headertext, the following css works great:
custom-banner::part(headertext) {
border: 5px solid green;
}
Now say I have something like this:
<custom-banner>
#shadow-root
<div part="headertext">
I am the header text!
<span>I am the subheader text!</span>
</div>
...
</custom-banner>
Is there a way to target the children of a shadow part? That is, something like this (which doesn't seem to work):
custom-banner::part(headertext) span {
border: 5px solid red;
}
I realize that this sort of thing might undercut the whole purpose of ::part, but maybe not?
To be clear, the subheader span is not a slotted child in this example. It is always part of the component and it is in the shadow dom. The examples above are meant to be the rendered component, in browser.
Thanks!
Alas, you can only style the ::part Node itself.
Not children, that would defeat the ::part purpose,
might as well allow all shadowDOM styling from the outside then. (can't be done)
You can specify a part="subheader",
or you could use a CSS property, scoped to the part, see --subheader: blue
good blogs:
Why is my shadowDOM inheriting styles
::parts by Monica Dinculescu (Google): https://meowni.ca/posts/part-theme-explainer/
<style>
body {
/* note how 'inheritable styles' do style shadowDOM */
font: 28px Arial;
color: green;
}
custom-banner::part(headertext) {
/* style shadowDOM from global CSS */
background: pink;
--subheader: blue;
}
</style>
<custom-banner></custom-banner>
<script>
customElements.define("custom-banner", class extends HTMLElement {
constructor() {
super()
.attachShadow({mode:"open"})
.innerHTML = `<style> span { color:var(--subheader) } </style>` +
`<div part="headertext">I am the header text!` +
`<span>I am the subheader text!</span>` +
`</div>`;
}
});
</script>

Vuetify custom styling of vuetify components like v-textarea with css

How can I target the underlying html textarea of a vuetify v-textarea with css? In my case I want to change the line-height, font-family, color and more of the v-textarea. It doesn't work like this:
<v-textarea class="custom-textarea"></v-textarea>
.custom-textarea {
line-height: 1;
color: red;
}
I also tried several other selectors like v-textarea, .v-textarea, v-text-field__slot but none of these worked either. What is the right selector for the textarea?
In order to override a deep element, you need to access the element through deep selectors like
::v-deep .v-textarea textarea
More information about deep selectors
.custom-textarea textarea {
line-height: 1;
color: red;
}
Set id prop of text-area and apply css style by id.
<v-textarea id="input-7-2"></v-textarea>
#input-7-2 {
color:white;
background-color: green;
line-height:1;
}
Codepen demo

Unable to apply simple CSS to an angular Materials element

Here's the Stackblitz.
I'm trying to apply the CSS color: blue to the div with class mat-button-toggle-label-content, but its not getting applied.
A similar CSS is getting successfully applied to a parent element called mat-button-toggle-group.
Just apply color to mat-button-toggle and keep it inside mat-button-toggle-group
Working stackblitz
mat-button-toggle-group {
background-color: orange;
mat-button-toggle {
color: blue;
}
}
You can apply the style to .mat-button-toggle-label-content but you need to break Encapsulation.
Component styles are encapsulated. You can't access component's styles(classes, ids) from outside of the component. You need to pierce into that component and inject the styles like below
Note: /deep/ is deprecated and no more recommended. So you can go with above approach. And for more details check Component Styles
mat-button-toggle-group {
background-color: orange;
/deep/ .mat-button-toggle-label-content {
color: blue;
}
}
There are many reason for that !
Your CSS may not be inserted properly into code
The order of material design CSS take over the order of CSS
My solution is that you may need to put !important after color: blue;
it is : color: blue !important;
Just move it to styles.scss and it will work Stackblitz.

How to maintain the existing background color of h3 element when hover on selected item

I have an accordion like control in which an item will be expanded and another will be collapsed. I have a common background color (which differs for various themes ) and a different hover color for all headers.
I need to maintain the background color for active item which is expanded and hover color need not to be applied for this item alone.
I have a class to identify this and I apply a certain background through hover selector
CSS
.e-active:hover {
background: #f00;
}
I tried with transparent and none but it changes the background to white
This is hard coded CSS but I need a generic CSS such that the existing background color will be maintained for active h3 element on hover state for any theme
You can use the :not css selector
div {
background: green;
padding: 2px 20px;
color: #ffffff;
}
h3 {
background: blue;
padding: 6px;
}
h3:not(.e-active):hover {
background: red;
}
<div>
<h3 class="e-active">Heading 1</h3>
<h3>Heading 2</h3>
<h3>Heading 3</h3>
</div>
You're probably going to need to include some form of JavaScript/jQuery to implement this dynamically (although I am certain you could use SASS/SCSS to achieve this dynamically as well).
The main focus of the script would be to check if the heading has the .e-active and not apply the .hover class in that instance. Once that's down, you can simply change :hover to .hover.
Here is an example - run the code snippet to see it work:
$('h1').mouseenter(function(){
if(!$(this).hasClass('e-active')) { //if heading does NOT have e-active class, apply hover effect
$(this).addClass('hover');
}
});
$('h1').mouseleave(function(){
$(this).removeClass('hover');
});
h1 {
background-color: salmon;
}
h1.hover {
background-color: teal;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Non active Heading 1</h1>
<h1 class="e-active">Active Heading 2</h1>
<h1>Non active Heading 3</h1>
EDIT:
Bhuwans answer that shows the use of the :not selector is a much cleaner way of achieving that - I would suggest using that route first whenever possible.

Changing other elements in CSS

I have always wonder why this wouldn't work as it would make so much sense.
CSS:
#button1:hover {
background: green;
#button2 {
background: red;
}
}
HTML
<button id="button1"></button>
<button id="button2"></button>
If I hover over Button1, Button2's background should also change.
Is there a workaround to this other than the use of Javascript?
You can use the adjacent selector,
#button1:hover {
Background: green;
}
#button1:hover + #button2 {
Background: red;
}
Have a look at all the css selectors: http://css-tricks.com/almanac/
Oh by the way it's only possible to apply css on hover to elements after the hovered element. Parent elements and elements before the hovered element cannot be styled with css on hover. It's a limitation of css.
This can be done but CSS lacks the ability to provide powerful conditional statements. However if you look into SASS CSS LESS it is starting to happen.

Resources