Emotion JS: How to apply styles to child when hover parent? - css

Seems like this question has been asked and answered many different ways, but the answers I've seen either don't apply to Emotion or the Emotion-related answered haven't worked for me. I'm on #emtion/core#10.0.28 and #emtion/styled#10.0.27.
Essentially I want to apply styles to a child component when the parent is hovered/active/focused. The parent is a button and the child is an optional icon. The following styles are added to the (parent) button via the styled syntax.
const iconWrapperStyles = (props) => {
return css`
${props.IconWrapper} {
width: ${iconSizeMedium};
height: ${iconSizeMedium};
margin-left: ${spacingSizeSmall};
color: ${textColor};
fill: ${textColor};
background: ${backgroundColor};
border-color: ${borderColor};
}
&:hover:not(:disabled),
&:focus:not(:disabled),
&:active:not(:disabled) ${props.IconWrapper} {
outline: none;
color: ${textColorHover};
fill: ${textColorHover};
background: ${backgroundColorHover};
border-color: ${borderColorHover};
}
`;
};
The first block of styles is successfully applied. Therefore, at first blush, the button and child icon appear properly styled. However, when you hover/focus/make active the button, the icon does not change. I've tried the implementation above, along with ... + ${IconWrapper} and ... & ${IconWrapper}; all three fail for me. Official docs indicate that the & should work.

Regardless of the JS framework, the following should always work.
button {
background: darkblue;
color: white;
border: none;
padding: 5px;
}
button:hover i {
color: red;
}
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<button>
<i class='icon-edit'></i> Click to edit
</button>
In your case, that becomes
${props.IconWrapper} {
width: ${iconSizeMedium};
height: ${iconSizeMedium};
margin-left: ${spacingSizeSmall};
color: ${textColor};
fill: ${textColor};
background: ${backgroundColor};
border-color: ${borderColor};
}
&:hover:not(:disabled) ${props.IconWrapper},
&:focus:not(:disabled) ${props.IconWrapper},
&:active:not(:disabled) ${props.IconWrapper} {
outline: none;
color: ${textColorHover};
fill: ${textColorHover};
background: ${backgroundColorHover};
border-color: ${borderColorHover};
}

I failed because my CSS is weak. Comma-separated CSS decorators do not iterate against the finally-declared element.
From this...
&:hover:not(:disabled),
&:focus:not(:disabled),
&:active:not(:disabled) ${props.IconWrapper} {
outline: none;
color: ${textColorHover};
fill: ${textColorHover};
background: ${backgroundColorHover};
border-color: ${borderColorHover};
}
To this...
&:hover:not(:disabled) ${props.IconWrapper}, // include child el
&:focus:not(:disabled) ${props.IconWrapper}, // include child el
&:active:not(:disabled) ${props.IconWrapper} {
outline: none;
color: ${textColorHover};
fill: ${textColorHover};
background: ${backgroundColorHover};
border-color: ${borderColorHover};
}

Related

Why css hover is affecting only bookmarks?

I have 5 links on site, they are styled with css, and they should turn black after mouse hovers on them. Links to extrenal pages doesn't turn black, only links to bookmarks on page are turning black.
I tried diffrent styling and nothing works. It works normally without React and without the server.
css styling:
.menu_link {
border: none;
text-decoration: none;
color: darkgreen;
height: 100%;
width: 20%;
text-align: center;
font-size: calc(1em + 1vw);
font-family: pokemon-hollow;
}
.menu_link:hover {
color: black;
background-color: beige;
}
.menu_link:visited, .menu_link:link {
color: darkgreen;
}
MenuLink class:
import React from 'react';
import './MenuLink.css'
class MenuLink extends React.Component {
render() {
return (
<a href={this.props.href} target={this.props.target} className="menu_link" >{this.props.name}</a>
)
}
}
export default MenuLink;
Menu class:
import React from 'react';
import './Menu.css';
import '../MenuLink/MenuLink'
import MenuLink from '../MenuLink/MenuLink';
class Menu extends React.Component {
render() {
return (
<div id='menu'>
<MenuLink id="main_container" name="Home"/>
<MenuLink href="https://bulbapedia.bulbagarden.net/wiki/Fennekin_(Pok%C3%A9mon)" name='Fennekin' target='_blank' />
<MenuLink href="https://bulbapedia.bulbagarden.net/wiki/Braixen_(Pok%C3%A9mon)" name='Braixen' target='_blank' />
<MenuLink href="https://bulbapedia.bulbagarden.net/wiki/Delphox_(Pok%C3%A9mon)" name='Delphox' target='_blank' />
<MenuLink id="main_container" name="Galery"/>
</div>
)
}
}
export default Menu;
No errors, but when I force on hover on link in chrome developer tools i get this:
color: black;
You are overriding .menu_link hover styles with these
.menu_link:visited, .menu_link:link {
color: darkgreen; /*this will override .menu_link:hover styles*/
}
If css specificity is exactly the same, order does matter. Styles declared later will be applied.
So change your css to the below:
.menu_link:visited, .menu_link:link,.menu_link {
border: none;
text-decoration: none;
color: darkgreen;
height: 100%;
width: 20%;
text-align: center;
font-size: calc(1em + 1vw);
font-family: pokemon-hollow;
}
.menu_link:hover {
color: black;
background-color: beige;
}
The problem was the order of lines.
.menu_link:visited, .menu_link:link {
color: darkgreen;
}
were after
.menu_link:hover {
color: black;
background-color: beige;
}
and they were overwriting hover selector. Changing the order to:
.menu_link:visited, .menu_link:link {
color: darkgreen;
}
.menu_link:hover {
color: black;
background-color: beige;
}
was what fixed the problem.
Bookmarks links weren't affected, probably because they can't have state :visited or :link.

Why is button element unaffected by CSS?

I have a problem with styling a button element. Here is the sample:
$clrWhite: #fff;
$clrPrimary: #3c9494;
.khanbank__button {
display: block;
height: 50px;
border: none;
color: $clrWhite;
cursor: pointer;
&--primary {
background: $clrPrimary;
&:hover {
background: darken($clrPrimary, 5%);
}
}
}
Here is the what i've tried:
Test
I see you are using BEM
The issue is on your HTML, as you need to have both classes applied to the element
<button class="khanbank__button khanbank__button--primary">Test</button>
From your Codepen, you wrote:
<button class="khanbank__button--primary">Test</button>
However, if I were to translate your SCSS into normal CSS, it would become:
:root {
--clrWhite: #fff;
--clrPrimary: #3c9494;
--clrPrimaryDarken: #358282;
}
.khanbank__button {
display: block;
height: 50px;
border: none;
color: var(--clrWhite);
cursor: pointer;
}
.khanbank__button--primary {
background: var(--clrPrimary);
}
.khanbank__button--primary:hover {
background: var(--clrPrimaryDarken);
}
<button class="khanbank__button--primary">Test</button>
Perhaps now you could see the problem.
In your HTML you have only applied .khanbank__button--primary to <button>. You need to also apply the base class .khanbank__button to it.
In short, your HTML should be:
<button class="khanbank__button khanbank__button--primary">Test</button>
See this pen for working example.

CSS Link/Hover Not Working

I have a link which should display white for 'regular' and hover, and light blue for active.
But it shows purple for 'regular'. Why?
.button {
text-decoration:none;
color: red;
background: purple;
}
.button:hover {
color: white;
background: purple;
}
.button:active {
color: red;
background: purple;
}
.button:visited {
color: purple;
background: purple;
}
text
HTML:
text
CSS:
<style>
.button {
text-decoration:none;
color: red;
background: purple;
}
.button:hover {
color: white;
background: purple;
}
.button:active {
color: red;
background: purple;
}
.button:visited {
color: purple;
background: purple;
}
</style>
If .button is an <A> tag as your CSS suggests you might want to provide styling for the "visited" pseudo class.
See: http://www.w3.org/wiki/CSS/Selectors/pseudo-classes/:visited
Additional Information
The cascading nature of CSS means that the style's order does matter.
Once a URL has been visited, the ":visited" styles will apply.
When you hover over the link, those styles will apply as well.
The priority in which they apply will depend on the order they are in your style sheet.
Note: If you want ":hover" to be dominant (even after visited happens, it should be defined below :visited.

Targeting image link and CSS

Basically I'm looking for a way to apply a specific style to an linked image like:
<img alt="" src="/media/XXXX.gif">
because my css can't do it despite a > img and i found that css3 can target specific a link depending on file type.So i try :
.HPDroite a[href$=".gif"] {
text-decoration: none;
}
.HPDroite a[href$=".gif"]:hover {
text-decoration: none;
border: 0;
}
but nothing change, it's worth than before !
So what's the way to apply specific style to an a img ?
EDIT: after explaination by captain, my code look like:
.PartieDroite1 p {
padding: 0.3em;
}
.PartieDroite1 a {
color: green;
padding: em(2px);
font-size: smaller;
}
.PartieDroite1 a:hover {
color: black;
background: green;
text-decoration: none;
}
.PartieDroite1 a > img[src$=".gif"] {
text-decoration: none;
}
.PartieDroite1 a > img[src$=".gif"]:hover {
text-decoration: none;
border: 0;
background: none;
}
My goal is to set off the background property on a a img:hover.
Not sure I understand the question but if you are looking to set some css rules specifically to the image inside the link, you can put the into a class and call like such:
<a class="mylink" href="http://XXXX"><img alt="" src="/media/XXXX.gif"></a>
Then, to add css rules to it, you may call
.mylink img
{
/*Your css rules here*/
}
Hope it helps.
You need to alter your CSS, this code doesn't make sense:
.HPDroite a[href$=".gif"] {
text-decoration: none;
}
this is saying "target a class of HPDroite with a child element of an a tag that has an href ending in .gif".
Thus not targeting the a tag at all, nor the image inside.
I altered your code and made a codepen for you to see my changes.
See here: Codepen with fixes
Notice that I altered your CSS showing you how to target the a tag and how to target the image inside, as well as some added fanciness ;)!
Hope this helps and good luck with the project.
Updates due to change in question:
.PartieDroite1 p {
padding: 0.3em;
}
.PartieDroite1 a {
color: green;
padding: em(2px);
font-size: smaller;
}
.PartieDroite1 a:hover {
color: black;
background: green;
text-decoration: none;
}
.PartieDroite1 a > img[src$=".gif"] {
text-decoration: none;
}
.PartieDroite1 a > img[src$=".gif"]:hover {
text-decoration: none;
border: 0;
background: none;
}
First of all, you are setting text-decoration on the image, this should only be on the a tag, since an image has no text, changes like so:
.PartieDroite1 a {
color: green;
padding: em(2px);
font-size: smaller;
}
.PartieDroite1 a:hover {
color: black;
background: green;
text-decoration: none;
}
.PartieDroite1 a > img[src$=".gif"] {
border: 0;
background: none;
}
.PartieDroite1 a > img[src$=".gif"]:hover {
background: pink;
}
This updates the image by default to have no border or background and still allows the a tag to have no text decoration.
As an example, I set the background of the image :hover to make the background pink.
"So what's the way to apply specific style to an a img ?"
Well, above I have demonstrated how to change the style of all images in the .PartieDroite1 > a > img - here:
.PartieDroite1 a > img[src$=".gif"] {
border: 0;
background: none;
}
and how to alter the image when hovered, here:
.PartieDroite1 a > img[src$=".gif"]:hover {
background: pink;
}
thus answering your question as I would interpret it.
So what's the way to apply specific style to an a img
To style a specific image format you would use:
This selector method
img[src$=".png"] {
border-color:yellow;
}
img {
border: 12px solid green
}
img[src$=".png"] {
border-color: yellow;
}
img[src$=".jpg"] {
border-color: red;
}
<img src="http://hello-kitty.sanriotown.com/images/kitty.png" alt="" />
<img src="http://static.tvtropes.org/pmwiki/pub/images/Hello_Kitty_Pink_2981.jpg" alt="" />
If the image in inside a link then the style would be :
.HPDroite a img[src$=".png"] {
border-color:yellow;
}
NOTE:
However, if you are trying to style the link based on the image format then that is not possible as there is no parent selector

Less nested rules get parent properties

Hello I am wondering is it possible to do something like this in less. I have this css:
.parent{display: block; color: red; border: yellow 1px solid;}
.parent a, .parent a.special-link{color: blue; border-color: green;}
I would write it in less like this:
.parent{
display: block;
color: red;
border: yellow 1px solid;
a, a.special-link{
color: blue; border-color: green;
}
}
And rules are ok but what if in further developing I have to add something to :hover but only for it eg. padding: 20px; What is the best way to do this? My first thought is that if there is some kind of workaround/hack/selector that allows to inherit all properties of parent.
I doubt I clearly understand your exact needs (":hover" of what? "only" for what "it"?)
But in general it usually goes like this:
.parent {
display: block;
color: red;
border: yellow 1px solid;
a {
// <a> properties:
// ...
&, &.special-link {
// <a> and <a.special-link> properties:
// ...
color: blue;
border-color: green;
}
&.special-link {
// <a.special-link> properties:
// ...
}
&:hover {
// <a:hover> properties:
// ...
}
/// etc. etc. etc.
}
}

Resources