When one element is hovered, change :before pseudo element as well - css

I have this button I am trying to make, when hovered, the button itself, and :before pseudo element
swap color schemes, as well as the arrow just inversing its color to still be visible, attached is the design system to visually represent the end goal.
I am unsure if pseudo elements can be changed in this manner, so I understand if I have to refactor a little bit, but here is the current snippet of code I am using:
HTML:
<header className="hero">
<div className="hero__img"></div>
<h1 className="hero__title">Modern Art Gallery</h1>
<p className="hero__desc">
The arts in the collection of the Modern Art Gallery all started from
a spark of inspiration. Will these pieces inspire you? Visit us and
find out.
</p>
<button className="hero__cta">Our Location</button>
</header>
SCSS:
&__cta {
font-family: $font-heading;
font-size: 2rem;
letter-spacing: 3.64px;
text-transform: uppercase;
color: $white;
background-color: $black;
border: none;
padding: 20px 25px;
text-align: center;
width: 204px;
height: 72px;
margin: 25px 15px;
position: relative;
transition: all 0.25s ease;
&::before {
position: absolute;
content: '';
content: url('../../public/assets/icon-arrow-right.svg');
width: 58px;
height: 72px;
background-color: $gold;
top: 0;
right: 0;
bottom: 0;
transform: translateX(100%);
display: flex;
justify-content: center;
align-items: center;
}
Thanks all!

Related

Why is the div tag not changing css by its className?

I have a piece of React code:
<div className="Tooltip-Wrapper" onMouseEnter={showTooltip} onMouseLeave={hideTooltip}>
{children}
{active && <div className="Tooltip-Tip">{text}</div>}
</div>
and have these classes in a scss file:
.Tooltip-Wrapper {
display: inline-block;
position: relative;
}
.Tooltip-Tip {
position: absolute;
border-radius: 4px;
left: 50%;
transform: translateX(-50%);
padding: 6px;
color: var(--tooltip-text-color);
background: var(--tooltip-background-color);
font-size: 14px;
font-family: sans-serif;
line-height: 1;
z-index: 100;
white-space: nowrap;
}
but the divs do not have this styling on them. What could be the reason? Thanks!
It's probably to do with one of the properties not being available for divs.
don't write "classname" instead of it just write "class", then it might work.

CSS : get last HTML tag with a given class, in a list where not every HTML tag has this class

THIS IS A DUPLICATE OF MY CLOSED QUESTION, BUT THE DUPLICATES ARE IRRELEVANT
First "duplicate"
It does not look at the class though, only the type, so if you happen to have non-articles with the same class you'll get unexpected results
Second "duplicate" is entirely something else.
Third "duplicate" is the explanation of why my try didn't work.
Fourth "duplicate" gives a workaround for the first element, not the last.
I have understood that there is no CSS selector for that, I juste want a solution. Be mindful of that before closing my question !
I have 5 buttons. They have an underlayer that make them seem they are active, as you will see in the snippet.
Each button can have an active state, but only starting from 1, and ending anywhere to 5.
They all have a divider, displayed in red in the snippet.
I would like to keep the divider into the underlayer, outside of the underlayer, but I would like to make it disappear at the end of the underlayer (in snippet, after button #2).
Following my first question, I understood that there is no CSS selector to do that. So what would be the best way to tackle this issue ?
.container {
display: flex;
align-items: stretch;
justify-content: start
margin: 12px;
position: relative;
}
button:after {
content: '';
height: 100%;
position: absolute;
background: red;
left: calc(100% + 12px);
width: 1px;
top: 0;
}
button.active:last-child:after {
content: none;
}
button {
flex: 0 0 calc(20% - 24px);
border: 0;
height: 32px;
color: black;
text-transform: uppercase;
text-align: center;
margin-right: 24px;
background: transparent;
position: relative;
}
button.active {
color: white;
}
.active-pill {
background: teal;
position: absolute;
height: 32px;
border-radius: 16px;
background: teal;
width: calc(40% - 12px);
z-index: -1;
}
<div class="container">
<div class="active-pill"></div>
<button class="active">Step 1</button>
<button class="active">Step 2</button>
<button>Step 3</button>
<button>Step 4</button>
<button>Step 5</button>
</div>
<h3>
Which selector to use to remove the content after button #2 ?
</h3>
In this particular case: Just put the divider on the left side of the buttons, instead of the right?
Then the one that doesn’t need one, becomes the first non-active one after the active ones, so it can easily be selected using button.active + button:not(.active):after
The first button here technically has a divider to the left as well then, that gets cut off here when the snippet gets rendered anyway. But in a situation where you’d need to explicitly “eliminate” it, you could still go with just plain and simple :first-child here (I’m assuming if there’s active buttons, it always starts with the first one, right?)
This is a bit similar to what Hao suggested in their answer, but with their version, the divider gets placed on the right on some buttons, on the left on others … I’d prefer to simply have it the same on all.
.container {
display: flex;
align-items: stretch;
justify-content: start
margin: 12px;
position: relative;
}
button:after {
content: '';
height: 100%;
position: absolute;
background: red;
right: calc(100% + 12px);
width: 1px;
top: 0;
}
button.active + button:not(.active):after {
content: none;
}
button {
flex: 0 0 calc(20% - 24px);
border: 0;
height: 32px;
color: black;
text-transform: uppercase;
text-align: center;
margin-right: 24px;
background: transparent;
position: relative;
}
button.active {
color: white;
}
.active-pill {
background: teal;
position: absolute;
height: 32px;
border-radius: 16px;
background: teal;
width: calc(40% - 12px);
z-index: -1;
}
<div class="container">
<div class="active-pill"></div>
<button class="active">Step 1</button>
<button class="active">Step 2</button>
<button>Step 3</button>
<button>Step 4</button>
<button>Step 5</button>
</div>
<h3>
Which selector to use to remove the content after button #2 ?
</h3>
Unfortunately, in pure css there is no way to select the last element with a specific class.
There are loads of possible solutions to your issue however. To name a few:
Since you can define your own tag-names in HTML5, you can rename the button elements with the active class to activebutton. That way you can target them with the :last-of-type selector. This might be the closest to what you are trying here. You could get rid of the underlayer as well...
You could indicate the active element in it's parent. In this case the container, and target the nth child.
You could add an extra class to the last active element in your html
You could go the javascript route...
.container {
display: flex;
align-items: stretch;
justify-content: start
position: relative;
margin-bottom: 12px;
}
button ,
buttona,
span{
padding: 0 50px;
border: 0;
height: 32px;
font-family: 'system-ui';
font-size: 11px;
line-height: 32px;
color: black;
text-transform: uppercase;
text-align: center;
background: transparent;
position: relative;
}
buttona,
span{
background: teal;
color: white;
}
button:after,
buttona:after,
span:after{
content: '';
height: 100%;
position: absolute;
background: red;
right: 0;
width: 1px;
top: 0;
}
buttona:first-of-type,
span:first-of-type{
border-top-left-radius: 16px;
border-bottom-left-radius: 16px;
}
buttona:last-of-type,
span:last-of-type{
border-top-right-radius: 16px;
border-bottom-right-radius: 16px;
}
buttona:last-of-type:after,
span:last-of-type:after{
display: none;
}
<div class="container">
<buttona>1</buttona>
<buttona>2</buttona>
<button>3</button>
<button>4</button>
<button>5</button>
</div>
<div class="container">
<span>1</span>
<span>2</span>
<span>3</span>
<button>4</button>
<button>5</button>
</div>

CSS: circle with background image when hovering over to hide text gets deformed

I am trying to have a number of circles that have background images and texts side by side. And I want when hovering over the circles the opacity of the image to change and also the text to disappear. Also, I don't want the underline sign for links to be shown. But I have a number of problems.
Here is my CSS code:
.ccont {
display: inline-block;
margin: 10px;
}
.circle {
position: relative;
height: 180px;
width: 180px;
border-radius: 50%;
justify-content: center;
align-items: center;
overflow: hidden;
display: table-cell;
vertical-align: middle;
text-align: center;
text-decoration: none;
padding: 0 10px;
}
.circle:after {
content: "";
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-image: url(http://deepchains.com/images/team.png);
background-size: cover;
background-repeat: no-repeat;
z-index: -1;
opacity: 0.2;
}
.circle__text {
padding: 1px;
background-color: none;
}
.circle:hover:after {
opacity: 1;
}
.ccont:hover {
font-size: 0;
}
and here is the HTML code:
<center>
<div class="circle">This is <br>Text1</div></div>
<div class="ccont" style="font-weight: bold"><div class="circle">Text2</div></div>
</center>
Here are the issues:
At the beginning when the page loads I see that because of a I get underline links under the images as is shown here:
When I hover over the left image, the text disappears but also the circle gets deformed as is shown here:
Finally when I hover over the right image its text correctly disappears as is shown here:
So here are my questions:
I have been trying to use text-decoration: none; in different places but I always see the underline marks under the images as they have links. How can I remove them?
Why when hovering over the left image, the image gets deformed, but the right image does not get deformed? The only difference is that the left image text has a <br> in it.
How can I have different background images for the left and right circles?
UPDATE:
I applied #chriskirknielsen solution and I get this:
The two images are not aligned correctly. It seems that the underlines are aligned and as two image texts have different heights it pushes two images to different vertical locations. If we can remove the underlines maybe this can be resolved?
It seems your sizing issue occurs because of box-sizing. Adding * { box-sizing: border-box; } at the start of your CSS fixes this issue because the padding from the text is taken into account when calculating the layout.
EDIT: OP's issue seems to be triggered by the font-size, so maybe just make the font transparent is the best idea?
.center {
text-align: center;
}
.ccont {
display: inline-block;
margin: 10px;
}
.cclink {
text-decoration: none;
}
.circle {
position: relative;
height: 180px;
width: 180px;
border-radius: 50%;
background-size: 0 0;
background-position: -9999px -9999px;
justify-content: center;
align-items: center;
overflow: hidden;
display: inline-flex;
text-align: center;
text-decoration: none;
padding: 0 10px;
}
.circle:after {
content: "";
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-image: inherit;
background-size: cover;
background-repeat: no-repeat;
z-index: -1;
opacity: 0.2;
}
.circle__text {
padding: 1px;
background-color: none;
}
.circle:hover:after {
opacity: 1;
}
.ccont:hover {
color: transparent;
}
<div class="center">
<a href="http://www.url1.html" class="cclink">
<div class="ccont" style="font-weight: bold">
<div class="circle" style="background-image: url(http://deepchains.com/images/team.png);">This is
<br>Text1</div>
</div>
</a>
<a href="http://www.url2.html" class="cclink">
<div class="ccont" style="font-weight: bold">
<div class="circle" style="background-image: url(http://deepchains.com/images/team.png);">Text2</div>
</div>
</a>
</div>
PS: Your HTML code is not very compliant to today's standards. The <center> tag is deprecated, and tags should be lowercase.

text background new line padding issue

I am dealing with text blocks (background blocks over text) and face some issues with paddings on new line. The problem occurs when the browser(e.g. mobile) cuts the text into to two lines due to lack of width. text then looks like this:
I don't really know how to set a padding css on the end of the new lines, since it could break up anywhere of the sentence. You could say put a span on it with padding, but it is not fixed where the line will break down. It depends on the width. Any recommendations?
You could apply display: inline-block but that will turn the background color into an ugly box which doesn't look as nice as having an exact width background for each line. Unfortunately CSS doesn't let us target individual lines except for the first one.
If you don't mind getting a little "creative" (or hacky) you could wrap each word in its own element in the backend or using JavaScript and apply the background color to those elements. Adjust the parent's word-spacing accordingly to eliminate gaps.
.main {
font-family: sans-serif;
font-weight: bold;
background-color: #99c;
display: flex;
height: 400px;
flex-direction: row;
align-items: center;
}
.text-container {
max-width: 500px;
display: inline-block;
word-spacing: -15px;
position: relative;
padding-left: 20px;
overflow: hidden;
}
.text-container::before {
content: '';
background-color: black;
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 100%;
z-index: 1;
}
span {
font-size: 36px;
line-height: 1.5em;
color: white;
background-color: black;
padding: 0.25em 0.5em 0.25em 0;
max-width: 360px;
}
<div class="main">
<div class="text-container">
<span>A</span> <span>Movie</span> <span>in</span> <span>the</span> <span>park:</span> <span>Kung</span> <span>Fu</span> <span>Panda</span>
</div>
</div>
You can use box-shadow for this issue and display inline:
<div class="text">
<span class="text-container">A Movie in the park: Kung Fu Panda</span>
</div>
And css:
.text > span {
display: inline;
box-shadow: 25px 0 0 black, -10px 0 0 black;
background-color: black;
color: white;
}
Try to add after "Park:" and before "Kung"
padding workded!!!
change width by console browser and see result:
h1{
background-color: #ff6a6a;
padding: 33px;
display: inline-block;
word-wrap: break-word;
width:300px
}
<h1>rert ert erttttttttttttttt 00000000000000000000 dfgdfgd dfgdfgdft ertert </h1>
Use <p> tag to wrap up the text and it apparently works demo
<div class="main">
<div class="text-container">
<p id="test">A Movie in the park: Kung Fu Panda</p>
</div>
</div>
css
.main {
font-family: sans-serif;
font-weight: bold;
background-color: #99c;
display: flex;
height: 400px;
flex-direction: row;
align-items: center;
}
.text-container {
max-width: 400px;
}
p {
font-size: 36px;
line-height: 2em;
color: white;
background-color: black;
padding: 0.5em;
max-width: 360px;
}

Css pointer-events hover issue

I have to following code:
<div class="playlist-item">
<a class="playlist-non-selected" href="#">
<span class="playlist-title">AudioAgent - Japanese Intro</span>
</a>
</div>
https://jsfiddle.net/4uyb7rh9/10/
The problem is when you rollover the text, in firefox and ie overPlaylistItem & outPlaylistItem are constantly called and cursor just keeps flickering. This works properly in chrome. Is there a way to make this work in all browsers?
This happens because when you set the class having pointer-events: none it triggers a mouse leave event, hence it flashes.
First of all, may I suggest you use :hover, second, whether you use :hover or script, you need to target the specific element that shouldn't be clickable, for example the span
.playlist-non-selected:hover span {
pointer-events: none;
}
Stack snippet
.playlist-item {
position: relative;
top: 0px;
left: 0px;
height: 40px;
margin-bottom: 5px;
overflow: hidden;
line-height: 40px;
}
.playlist-title {
display: inline-block;
position: relative;
top: 0px;
margin-left: 20px;
overflow: hidden;
font-size: 22px;
font-family: 'Gnuolane Free';
margin-bottom: 0px;
}
.playlist-non-selected {
color: #bbb;
}
.playlist-non-selected:hover{
color: red;
}
.playlist-non-selected:hover span{
pointer-events: none;
}
<div class="playlist-item">
<a class="playlist-non-selected" href="#">
<span class="playlist-title">AudioAgent - Japanese Intro</span>
</a>
</div>
And here is an updated fiddle using your script
Update based on comment about not working in Edge
Appears to be some kind of bug in Edge when the span has display: block so changing it to display: inline-block and it works.
For it to work in IE11, the span need display: inline (or just remove the display:...) so it use its default.
Update 2 based on comment about not working in Edge
If you need the span to display as block, changing it to a div and it works in both Edge and IE11.
An updated fiddle using your script
Why haven't you used :hover ? This can be done with CSS easily and will not pose any difficulty for browsers compatability like
.playlist-item {
position: relative;
top: 0px;
left: 0px;
height: 40px;
margin-bottom: 5px;
overflow: hidden;
line-height: 40px;
}
.playlist-title {
display: block;
position: relative;
top: 0px;
margin-left: 20px;
overflow: hidden;
font-size: 22px;
font-family: 'Gnuolane Free';
margin-bottom: 0px;
backface-visibility:hidden
}
.playlist-non-selected:hover{
color: red;
pointer-events: none;
backface-visibility:hidden
}
.playlist-non-selected {
color: #bbb;
}
<div class="playlist-item">
<a class="playlist-non-selected" href="#">
<span class="playlist-title">AudioAgent - Japanese Intro</span>
</a>
</div>

Resources