I have a button that has a background color slide in from the right on hover, which works fine, however I need the text color to change as well. I have managed to have it fade, but that doesn't work properly. What I would like is a color transition slide in from the right in concert with the background change.
.slideybutton {
background-size: 200% 100%;
background-image: linear-gradient(to right, white 50%, blue 50%);
transition: background-position 1s linear, color 1s linear;
color: blue;
}
.slideybutton:hover {
background-position: -100% 0;
color: white;
}
<a class="slideybutton">
Lorem ipsum dolor sit amet.
</a>
I have seen this question, but the only solution is unfeasible in this instance.
Sliding in changing text color animation
Is there some CSS trick I am missing? Google searches don't result in anything pointing me in the right direction, so I am concerned I am attempting the impossible.
I'm happy to utilise JS or jQuery if it will accomplish what I want.
This could be done by "combining the text with the background", the key is property background-clip, check this out:
.slideybutton {
background-size: 200% 100%;
background-image: linear-gradient(to right, blue 50%, white 50%),
linear-gradient(to right, white 50%, blue 50%);
transition: background-position 1s linear;
-webkit-background-clip: text, border-box;
background-clip: text, border-box;
color: transparent;
}
.slideybutton:hover {
background-position: -100% 0;
}
<a class="slideybutton">
Lorem ipsum dolor sit amet.
</a>
Just providing an alternative using pseudo elements. Works fine on chrome.
.slideybutton {
position: relative;
}
.slideybutton:hover {
/* to fix a bug in IE */
}
.slideybutton:hover::after {
width: 100%;
}
.slideybutton::before {
content: attr(title);
color: blue;
}
.slideybutton::after {
content: attr(title);
position: absolute;
left: 0;
width: 0;
top: 0;
bottom: 0;
color: white;
transition: width 1s linear;
background-color: blue;
white-space: nowrap;
overflow: hidden;
}
<a class="slideybutton" title="Lorem ipsum dolor sit amet.">
</a>
i don't think you'll be able to do this elegantly using a pure css solution at the moment. backdrop filters look promising for what you want to achieve - you would slowly overlay an element with a backdrop filter - this would apply the filter to the text as you move across it.
Check out more here https://webkit.org/demos/backdrop-filter/
Related
This question already has answers here:
Use CSS3 transitions with gradient backgrounds
(19 answers)
How to Animate Gradients using CSS
(5 answers)
Closed 6 months ago.
This post was edited and submitted for review 6 months ago and failed to reopen the post:
Original close reason(s) were not resolved
How do I add an animation from plain color to background gradient color when hovered? Possibly when hovered from left to right?
I have this sample code but when hovered it is too instant when changing the colors.
I've tried using these references:
Use CSS3 transitions with gradient backgrounds
Animating Linear Gradient using CSS
But can't seem to figure out how to have an easiest approach for the hover. Other references say to add pseudo after element when hovered, but it seems a bit complicated when using it. Just want to use the hover element when animating the gradient text to it.
How to add a transition with these types of gradient text colors?
SAMPLE CODE:
.hover-grad-txt {
font-size:100px;
text-align:center;
color:#191335;
background-image:linear-gradient(to right, #191335, #191335);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
transition:all 0.4s ease-in-out;
}
.hover-grad-txt:hover {
background-image:linear-gradient(to right, #01A5F8, #01BFD8);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
<span class="hover-grad-txt">Spear</span>
To animate it, instead of trying to animate the gradient, you could animate it's position.
Let's use a new linear gradient for you background.
It will go from the solid color, then it will be a gradient to your
first color from the gradient, then it will be a gradient to the second color of your gradient.
Something like this:
background-image:linear-gradient(to right, #191335, #191335 33.33333%, #01A5F8 66.66666%, #01BFD8);
Then you adapt the size to only see the solid color:
background-size: 300% 100%;
And it's position:
background-position: top left;
All you need to do on hover is to move it:
background-position: top left 100%;
.hover-grad-txt {
font-size:100px;
text-align:center;
color:#191335;
background-image:linear-gradient(to right, #191335, #191335 33.33333%, #01A5F8 66.66666%, #01BFD8);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 300% 100%;
background-position: top left;
transition:all 1s ease-in-out;
}
.hover-grad-txt:hover {
background-position: top left 100%;
}
<span class="hover-grad-txt">Spear</span>
Using new CSS properties, you could also do it like this:
<!DOCTYPE html>
<html>
<head>
<style>
#property --a {
syntax: '<color>';
inherits: false;
initial-value: #191335;
}
#property --b {
syntax: '<color>';
inherits: false;
initial-value: #191335;
}
.hover-grad-txt {
transition: --a 0.5s, --b 0.5s;
font-size: 100px;
text-align: center;
background-image: linear-gradient(to right, var(--a), var(--b));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.hover-grad-txt:hover {
--a:#01A5F8;
--b: #01BFD8;
}
</style>
</head>
<body>
<span class="hover-grad-txt">Spear</span>
</body>
</html>
Keep in mind it only works in Chrome. Also, look at this question.
In addition to these answer, you could also utilize #keyframes to specify the animation code. Example here is setting pretty as the #keyframe and placing rgba value with Alpha set to 0 to ensure hovering occurs still. I place crimson color as to see the changes more obvios.
.hover-grad-txt {
background: linear-gradient(to right, crimson, #01A5F8, #01BFD8);
background-size: 200% 200%;
animation: pretty 2s ease-in-out infinite;
background-clip: text;
-webkit-background-clip: text;
transition: color 1s ease-in-out;
font-size: 100px;
}
.hover-grad-txt:hover {
color: rgba(0, 0, 0, 0);
}
#keyframes pretty {
0% {
background-position: left
}
50% {
background-position: right
}
100% {
background-position: left
}
}
<div class="hover-grad-txt">Spear</div>
I am trying to make some RGB text, and that works, however when I am trying to make a ::selection then it will hide the text, and will for some reason take the background color of the text. I have tried anything I can think of, for now, I am making it for chrome and will later work on firefox.
Research
In my research, I have found that you do not need to use a selector like .rgb. While looking into some documentation/examples, I have encountered multiple weird things, like when I was using .rgb::selection I could not higlight/select ANY text on the screen.
when I looked into W3schools they simply use
::selection {
color: red;
background: yellow;
}
and it works. Ive asked my teachers, and my peers. What none of them understand is why the ::selection is taking the animate property. What I have thought is that when I use -webkit-background-clip that is what is making it not work properly. If this is the case then how can I make it so that it still takes it. When I read some more, I tryed to use !important, this was the closest that I got. It made the text white, but the color was still changing in the background. I've looked here to try to learn how i can use it properly, but i think I have used it correctly. I just cant seem to get the background color to stay one color.
This is what I have gotten so far.
#import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght#0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
* {
margin: 0;
padding: 0;
background-color: #1e1e1e;
font-family: 'Montserrat', sans-serif;
}
.rgb
{
position:fixed;
background: linear-gradient(to right, #008AFF, #00FFE7);
animation:animate 10s forwards infinite;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
::selection !important{
background: red;
color: white;
}
#keyframes animate
{
0%, 100%
{
filter:hue-rotate(0deg);
}
50%
{
filter:hue-rotate(360deg);
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1 class="rgb">Welcome to my webpage</h1>
</body>
</html>
I've looked all over this site for something or someone with this problem but it seems I'm a first.
To escape the filter' a somewhat hacky way of doing it might be to have a second copy of the heading which is placed over the original and is actually the element for which selection takes place.
Its text and background are transparent until there is a selection at which point the selection (only) becomes white and red respectively.
#import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght#0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
* {
margin: 0;
padding: 0;
background-color: #1e1e1e;
font-family: 'Montserrat', sans-serif;
}
.rgb {
position: fixed;
background: linear-gradient(to right, #008AFF, #00FFE7);
animation: animate 10s forwards infinite;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.shadow {
color: transparent;
position: absolute;
top: 0;
left: 0;
background-color: transparent;
}
.shadow::selection {
background: red;
color: white;
}
#keyframes animate {
0%,
100% {
filter: hue-rotate(0deg);
}
50% {
filter: hue-rotate(360deg);
}
}
<h1 class="rgb">Welcome to my webpage</h1>
<h1 class="shadow">Welcome to my webpage</h1>
Hi I am trying to create a highlight on a CSS shape as shown below.
There will also be content inside of the hexagon including image and text,
The highlight I am referring to is the part in the top left.
the code I currently have for creating the hexagon is:
HTML
<div class="hexagon-big"></div>
CSS
.hexagon-big {
position: relative;
width: 200px;
height: 115.47px;
background-color: #343434;
}
.hexagon-big:before,
.hexagon-big:after {
content: "";
position: absolute;
width: 0;
border-left: 100px solid transparent;
border-right: 100px solid transparent;
}
.hexagon-big:before {
bottom: 100%;
border-bottom: 57.74px solid #343434;
}
.hexagon-big:after {
top: 100%;
width: 0;
border-top: 57.74px solid #343434;
}
There is other code for the content but i left it out because I don't think it is necessary
Do the hexagon shape differently and you can rely on gradient to create that highlight effect:
.hex {
width: 200px;
display: inline-flex;
margin:0 5px;
background:
conic-gradient(at top,#000 230deg, #0000 0),
linear-gradient(to bottom left,#fff , #000 60%);
clip-path: polygon(0% 25%,0% 75%,50% 100%,100% 75%,100% 25%,50% 0%);
}
.hex::before {
content: "";
padding-top: 115%; /* 100%/cos(30) */
}
<div class="hex"></div>
The solution in this answer is heavily based on the previous answer. To use clip-path and stacked gradients is by far the smartest thing to do here, but I still wanted to post this in order to show, how this solution could be improved and adjusted for your use case (text box, coloring, variables for maintenance, etc.).
.hexagon-big {
/* define box and text space */
width: 200px;
height: 230px;
padding: 10.8% 5px; /* adjust text box padding here; mind that top/bottom tip are part of the box */
box-sizing: border-box; /* width/height should include padding */
/* text formatting (optional) */
color: white;
text-align: center;
/* hex shape */
--hex-col: hsl(0deg 0% 20%); /* just your #343434 as a HSL color */
--hex-shadow: hsl(0deg 0% 50%); /* increased lightness by 15% to define highlight root color; 100% would be fully white */
background:
conic-gradient(at top, var(--hex-col) 232deg, transparent 0), /* change the angle of the shadow at "232deg": increase → narrower, decrease → wider */
linear-gradient(to bottom left, var(--hex-shadow), var(--hex-col) 55%);
clip-path: polygon(0% 25%,0% 75%,50% 100%,100% 75%,100% 25%,50% 0%);
}
<div class="hexagon-big">
Lorem ipsum dolor sit amet...
</div>
It should also be mentioned that your current way of using border is well better supported by older browsers than clip-path and conic-gradient (same with var()).
If this should be a problem, you might have to add another HTML tag and work out a way with transform: matrix(...) and box-shadow: inset ... (for example).
I cannot figure out why this breaks it. I have an a element which uses CSS transitions to fade into a gradient background on hover. For whatever reason whenever I set the text color on hover to white the transition breaks?
.social-item {
margin-left: 0.25vw;
padding: 0.1vw;
transition: 0.2s;
color: white;
}
.social-item:hover {
background: linear-gradient(to left, #8E2DE2, #DC0486);
color: white;
}
<i class="fab fa-keybase"></i> Keybase
I'm also using Bulma and Font Awesome.
You can't simply make transitions with background gradients.
Animatable CSS Properties
Use pseudo-element and do an opacity transform.
.social-item {
position: relative;
color: white;
z-index: 1;
}
.social-item::before {
position: absolute;
content: "";
top: 0;
right: 0;
bottom: 0;
left: 0;
background-image: linear-gradient(to left, #8e2de2, #dc0486);
z-index: -1;
transition: opacity 0.5s linear;
opacity: 0;
}
.social-item:hover::before {
opacity: 1;
}
<i class="fab fa-keybase"></i> Keybase
A nice article about this.
Thank you!
What I figured your problem to be is that you're trying to do gradient transition. It is not supported. But if you want to simulate it, you can use the opacity property in css. Add opacity: 0 to the main element (.social-item) and opacity: 1 to the hover state (.social-events:hover). Hence the transition: 0.2 will apply on the opacity, as it is supported, thus simulating the desired outcome.
Thus the final css, shall be.
.social-item {
margin-left: 0.25vw;
padding: 0.1vw;
transition: 0.2s;
color: white;
opacity:0;
}
.social-item:hover {
background: linear-gradient(to left, #8E2DE2, #DC0486);
color: white;
opacity: 1;
}
If you actually want to have the thing display normally, and not just on hover, then opacity: 0 wont work for you. You have to use the pseudo-selector :after to add a dummy element to the main class and work all the transitions and background gradient stuff on that. Here is a codepen example.
I have an video tag with an div displayed on top. The div is pretty nice looking and visible for the most part, only dark images are a bit problematic.
For the sake of testing I searched out 3 pictures and overlayed them with my div.
The question is, how would someone create this overlay layout, so it is discreetly and clearly visible at the same time?
The result is as follows:
Visibility good!
Visibility bad
Visibility okay, background visibility bad
.container{
position: relative;
}
img{
width: 100%;
height: 100%;
}
.tag{
position: absolute;
bottom: 5px;
right: 0;
color: white;
font-size: 48px;
padding: 5px;
-webkit-border-top-left-radius: 20px;
-moz-border-radius-topleft: 20px;
border-top-left-radius: 20px;
background-color: black;
opacity: 0.4;
filter: alpha(opacity=40); /* For IE8 and earlier */
}
<div class="container">
<img src="https://www.nasa.gov/sites/default/files/20140824_0304_171.jpg"></img>
<div class="tag">Hello Tag</div>
</div>
<div class="container">
<img src="https://alifebeyondrubies.files.wordpress.com/2013/03/walls01.jpg"></img>
<div class="tag">Hello Tag</div>
</div>
<div class="container">
<img src="http://photos.epicurious.com/2015/01/12/54b4006b2413537c0d45738f_51143820_spaghetti-mussels-white-beans_6x4.jpg"></img>
<div class="tag">Hello Tag</div>
</div>
Although perhaps better suited for UX.SE, there are a couple of options I might offer.
Firstly, don't use opacity for the whole element, use a transparent background color to allow the white text to stand out.
Secondly, outlining the black(ish) tag in white (or a transparent white) will allow the element to be more visible on darker backgrounds but not affect those with lighter colors.
JSfiddle Demo
.tag{
position: absolute;
bottom: 5px;
right: 0;
color: white;
font-size: 48px;
padding: 5px;
-webkit-border-top-left-radius: 20px;
-moz-border-radius-topleft: 20px;
border-top-left-radius: 20px;
background-color: rgba(0, 0, 0, 0.4);
box-shadow: -1px -1px 0px 0px rgba(255,255,255,0.3);
}
IMHO, make the text white and add a drop shadow.
.tag {
color: #fff;
text-shadow: 0 1px 10px rgba(0,0,0,0.75)
}
Apparently you are concerned that one hardcoded background color does not suit all dark, neutral and light backgrounds.
There is a relatively new CSS property called background-blend-mode which controls how two backgrounds are blended with each other. You can use this property to specify a blending mode that produces some contrast in all situations.
The downsides:
Both image and overlay must be part of an element's background (mix-blend-mode is a better option with lesser support)
The overlay color must be chosen stategically. In the following example I used transparent white instead of transparent black since difference filter does not affect black color.
.photo {
position: relative;
height: 200px;
background-blend-mode: difference, normal;
}
.photo span {
position: absolute;
left: 0;
right: 0;
bottom: 0;
font: bold larger/50px sans-serif;
color: rgba(255, 255, 255, 1);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.photo-1 {
background:
linear-gradient(to right, rgba(255, 255, 255, .4), rgba(255, 255, 255, .4)) no-repeat bottom / 100% 50px,
url(https://www.nasa.gov/sites/default/files/20140824_0304_171.jpg) center / cover;
}
.photo-2 {
background:
linear-gradient(to right, rgba(255, 255, 255, .4), rgba(255, 255, 255, .4)) no-repeat bottom / 100% 50px,
url(https://alifebeyondrubies.files.wordpress.com/2013/03/walls01.jpg) center / cover;
}
.photo-3 {
background:
linear-gradient(to right, rgba(255, 255, 255, .4), rgba(255, 255, 255, .4)) no-repeat bottom / 100% 50px,
url(http://photos.epicurious.com/2015/01/12/54b4006b2413537c0d45738f_51143820_spaghetti-mussels-white-beans_6x4.jpg) center / cover;
}
<div class="photo photo-1"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</div>
<div class="photo photo-2"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</div>
<div class="photo photo-3"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</div>
what about using text / box-shadow? You could apply a text-shadow with white or black, and or a box-shadow to your .tag class. This way
there will be enough contrast.
Another way would be, using the same Image as a background Image on
the tag, and applying filter to it. (hue-rotate or brightness etc.)
Something else that comes to my mind would be a calculation using
canvas, to detect whether the bottom corner is dark or light, and
adding another class to the .tag, so that you can use two versions.
One for each type of background
Lastly maybe blend-modes are an option: mix-blend-mode: difference;