changing only alpha unknown color - css

I have few classes:
.overlay-blue {background-color: rgba(0,123,238,0.9);}
.overlay-orange { background-color:rgba(240,116,7,0.9); }
.overlay-purple { background-color:rgba(126,64,228,0.9); }
.overlay-green { background-color:rgba(57,151,95,0.9) }
.overlay-pink { background-color:rgba(173,33,106,0.9); }
.overlay-light-blue {background-color:rgba(0,183,168,0.9) }
.overlay-red {background-color:rgba(235,50,89,0.9); }
.overlay:hover
{
-webkit-animation-duration: 0.5s;
-webkit-animation-name: fadeInFromNone;
background-color: rgba(0,0,0,0.3);
}
#-webkit-keyframes fadeInFromNone {
0% {display:block; background-color: rgba(0,0,0,0.9);}
1% {display: block ; background-color: rgba(0,0,0,0.89);}
100% {display: none ; background-color: rgba(0,0,0,0.3);}
}
`
this function of hovering is working well but it turns the overlay to black when starging the animation because of the line
0% {display:block; background-color: rgba(0,0,0,0.9);}
which makes sense.
is there a way to dim the alpha channel without duplicating the code for each color?

There is no easy way going about your current approach, because it is impossible to target just the alpha channel in the rgba() property separately and change it. What you can do, however, is instead of setting a background colour on your element, set the background colour of a pseudo-element stretched to the full dimension of its parent, and only declare the rgb() values. The alpha channel changes can be delegated to the opacity property instead. I call this the pseudo-element approach:
Pseudo-element approach
/* Define BG colours of pseudo element instead */
.overlay-blue::before { background-color: rgb(0,123,238);}
.overlay-orange::before { background-color:rgb(240,116,7); }
/* and more... */
/* Set relative positioning of parent element */
.overlay {
position: relative;
}
/* Stretch pseudo element, declare empty content so it will show */
.overlay::before {
content: '';
opacity: .9;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
transition: all .5s ease-in-out;
z-index: -1;
}
/* Change opacity when parent element is hovered upon */
.overlay:hover::before {
opacity: 0.3;
}
Of course this is a rather basic implementation of your question (see demo fiddle here), because I do not know the exact details you want to achieve with your animation keyframes. The good thing is that pseudo-elements can also be animated :)
SASS approach
Even better: Alternatively, you might want to consider using a CSS preprocessor (SCSS, LESS) so that you can use variables, and do not have to repetitively redeclare the background colours. See the demo here.
You can use the following mixin:
/* Declare mixin */
#mixin overlayColor($color) {
background-color: rgba($color, 0.9);
&:hover { background-color: rgba($color, 0.3); }
}
/* Use #include for each colour class, you only have to declare the rgb(a) values */
.overlay {
margin-bottom: 10px;
padding: 20px;
position: relative;
transition: all .5s ease-in-out;
&.overlay-blue {
#include overlayColor(rgb(0,123,238));
}
&.overlay-orange {
#include overlayColor(rgb(240,116,7));
}
/* and more... */
}

Related

Can hover text be displayed automatically on mobile devices?

I am using a website template on Cargo Collective. On the Home page, there is a grid of images with text that only appears on hover. In Mobile view, the text does not appear. I understand hover doesn't work consistently on mobile devices. Is there a way to set this text to appear when the page loads on mobile?
Alternatively, how would I remove the hover functionality and have the text always visible?
Here are the two spots where hover appears in the CSS:
[data-predefined-style="true"] bodycopy a:hover {
}
bodycopy a.image-link,
bodycopy a.icon-link,
bodycopy a.image-link:hover,
bodycopy a.icon-link:hover {
border-bottom: 0;
padding-bottom: 0;
}
/**
* Thumbnail Hover
*/
.thumbnails .thumbnail > a {
position: relative;
}
.thumbnails .thumbnail .title {
background: rgba(0, 0, 0, 0.4);
padding: 0.5rem 1.2rem 0.7rem 1.2rem;
margin: 2.4rem;
color: rgba(255, 255, 255, 1);
align-content: center;
display: flex;
position: absolute;
left: 0;
top: 0;
z-index: 9;
opacity: 0;
}
.thumbnails .title span {
margin: auto;
display: inline-block;
}
.thumbnails .thumbnail:hover .title {
opacity: 1;
}
body.mobile .thumbnails .thumbnail:hover .title {
opacity: 0;
}
Out if this part we can make something up.
body.mobile .thumbnails .thumbnail:hover .title {
opacity: 0;
}
What if we removed the .thumnails:hover and changed the opacity to 1? it might do the trick.
body.mobile .thumbnails .title {
opacity: 1;
}
I hope this works but I have no Idea about Cargo Collective. Just using css knowledge.
I recommend to you to learn some css basics. This will help you to solve problem like this in the future.
Here's a small example showing how you could hide and display text depending on the width of the viewport using media queries. A similar method can be applied to your problem by only setting the :hover properties when the screen has a given minimum width.
Also note, that that device-width has been depreciated and removed from Web standards. So be careful when choosing your media query.
/* General styles */
p {
transition: opacity 0.3s;
}
/* Small styles */
.large {
opacity: 0;
}
.small {
opacity: 1;
}
/* Large styles */
#media only screen and (min-width: 640px) {
.large {
opacity: 1;
}
.small {
opacity: 0;
}
}
<p class="large">I'm visible when the screen is large!</p>
<p class="small">I'm visible when the screen is small!</p>
I should also mention that this is by no means a perfect solution. If you want to be more accurate, I would recommend using Javascript to detect the device type and modify your classes via Javascript.

CSS Animations - set duration on responsive animations

I'm trying to learn CSS animations and one thing I can't figure out and couldnt find on the web is how to set the proper duration.
I'm trying to have my website responsive therefore the font size would change depending on the size of the view. I have the following code so far:
#media screen {
.EntranceDiv{
top: 40%;
position: relative;
}
h1 {
font-size: 4rem;
margin: 0px;
}
.helloworld{
overflow: hidden; /* Ensures the content is not revealed until the animation */
border-right: .15em solid #D9FAFF; /* The typwriter cursor */
white-space: nowrap; /* Keeps the content on a single line */
margin: 0 auto; /* Gives that scrolling effect as the typing happens */
letter-spacing: .8em;
display: inline-block;
animation:
typing initial steps(30, end),
blink-caret .5s step-end infinite;
}
#keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: #D9FAFF }
}
#keyframes typing {
from { width: 0 }
to { width: 65% }
}
}
My problem is that with the changes in the font size, the animation either goes for too long or for too short and then the whole thing just pops on the screen. What is a good way of setting duration for responsive animations
Your main issue here is that the width you set is relative to parent container so it has no relation with the content of your inline-block element. You need to find a way to correctly set the width of the element.
Since you cannot make a transition to width:auto, here is an idea where I duplicate the content and I use a pseudo-element with absolute position. The first content will define the width and will be hidden and the second one will be visible and I can stretch to fit the defined width using left/right properties:
h1 {
font-size: 4rem;
margin: 0px;
}
.helloworld {
letter-spacing: .8em;
display: inline-block;
position:relative;
visibility:hidden;
white-space: nowrap;
}
.helloworld:after {
content:attr(data-content);
display:block;
visibility:visible;
overflow: hidden;
white-space: nowrap;
position:absolute;
top:0;
left:0;
bottom:0;
right:100%;
border-right: .15em solid #D9FAFF;
animation: typing 2s steps(30, end) forwards, blink-caret .5s step-end infinite;
}
#keyframes blink-caret {
from,
to {
border-color: transparent
}
50% {
border-color: #D9FAFF
}
}
#keyframes typing {
from {
right:100%
}
to {
right: 0%
}
}
}
<h1 data-content="lorem" class="helloworld">
Lorem
</h1>
<h1 data-content="lor" class="helloworld">
Lor
</h1>
<h1 data-content="lorem ipsume" class="helloworld">
Lorem ipsume
</h1>

What does “#keyframe doesn't cascade" mean?

I was reading this, it says
#keyframes rules don't cascade, so animations never derive keyframes
from more than one rule set.
what does "cascade" mean here? English is not my native language and there is no more detailed explanation so I don't understand what it means. Can anyone explain this with an example?
An example of CSS cascading: -
h1 {
font-size: 12px;
width: 200px; /* Sets width */
}
h1 {
font-size: 14px; /* Overrides 12px rule above */
height: 200px; /* Sets height */
}
In the above example the h1 elements font size is first set to 12px in the first rule and then overridden to be 14px by the second rule. The width is set in the first rule and the height is set in the second rule. This is cascading: multiple rules determine the final styles applied, with priority given to properties in the rules descending order.
An example of Keyframes cascading
/* WILL NOT CASCADE */
#keyframes exampleAnimation {
0% { top: 0; left: 0; margin: 10px; }
100% { top: 100px; margin: 20px; }
}
#keyframes exampleAnimation {
0% { top: 0; left: 0; }
100% { top: 0; left: 100px; }
}
The above example will not cascade. That is to say, only the last rule declaration is used for the animation. The animation will move the animating element 100px to the left, it will ignore the top and margin animations set in the previous rule declaration.

crossfading div backgrounds on :hover - possible in CSS?

Is there a way to smooth the transition during a div background change? Ideally I'd like to do this within the css, and not use any js.
In my css I have:
.examplediv {
background: url(img_img.png);
}
.examplediv:hover{
background: url(brighter_img.png);
}
It's doing what I'd like it to do (changing pictures), but if there was a way to make the two backgrounds "dissolve" into one another, I'd start frothing at the mouth with gratitude.
Note: The effect I'm going for is essentially an opacity change, so if it's easier to code a dissolve with :opacity, I'm all ears!
Tanks!~
It's definitely possible using just CSS. See this Fiddle for an example: https://jsfiddle.net/ffqdmcws/
HTML:
<div class="crossfade">
<div class="static"></div>
<div class="hover"></div>
</div>
CSS:
.crossfade {
position: relative;
width: 300px;
height: 200px;
}
.static, .hover {
position: absolute;
width: 100%;
height: 100%;
transition: opacity 1s ease;
}
.static {
background: url('http://lorempixel.com/300/200/food');
opacity: 1;
}
.hover {
background: url('http://lorempixel.com/300/200/cats');
opacity: 0;
}
.crossfade:hover > .static {
opacity: 0;
}
.crossfade:hover > .hover {
opacity: 1;
}
In this case I've got a container div using the crossfade class, and a couple of other divs inside that, using classes static and hover.
The static class contains the background to be shown initially, and the hover class contains the background to fade to on hover. The initial opacities are 1 for the static class and 0 for the hover class, so you only see the div with class static.
Then, if you hook up the hover action on the container div using .crossfade:hover, in order to set opacity: 0; for static and opacity: 1; for hover, that hides static and shows hover, when you hover over the container div.
Finally, to make the backgrounds overlap use absolute positioning of the two internal divs, so they're on top of each other at all times. Additionally, for the true crossfade effect you need the transition: opacity 1s ease; rule, which says you want the opacity to transition over a period of 1 second instead of switching instantly. Both the divs changing opacity from 1->0 and from 0->1 give you the crossfade effect of the background images.
You can do it with pseudo elements which are absolutely positioned. One is visible by default and another one on hover.
.examplediv {
height: 600px;
position: relative;
}
.examplediv:before, .examplediv:after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
transition: opacity 0.5s ease-out;
}
.examplediv:before {
background: url(https://pixabay.com/static/uploads/photo/2015/07/19/17/38/flower-851725_960_720.jpg)
}
.examplediv:after {
background: url(https://pixabay.com/static/uploads/photo/2015/12/07/23/56/pink-flower-1081646_960_720.jpg);
opacity: 0;
}
.examplediv:hover:before {
opacity: 0;
}
.examplediv:hover:after {
opacity: 1;
}
<div class="examplediv">
</div>
JSFIDDLE

Change Colour Opacity When Dont know RGB values only Alpha

I am attempting to change a buttons colour to 50% opacity when hovered over. This is simple enough when I know what the colour is but it will change at runtime.
Any ideas how I can do this with CSS3? I know I could do this easily with LESS but its not available to me.
.my-btn {
background-color: rgba(255,0,0,1); /* Will change at run time to anything */
}
.my-btn:hover {
background-color: rgba(?,?,?,0.5); /* I dont know what the rgb values will be */
}
Problem
Using the opacity property on the button itself would affect the text of the button; not ideal.
Solution
Apply the background color to a pseudo-element instead and layer it underneath the text with negative z-index. When needed, use the opacity property on the pseudo-element to create your transparent background.
Example
Note: Pseudo-elements cannot be applied to the <input> element as it cannot have children. This will only work with elements that can have children, such as <button> and <a>.
button {
position: relative;
background: none;
border: solid 1px #EEE;
padding: 10px;
border-radius: 5px;
overflow: hidden;
}
button:before {
content: '';
position: absolute;
top: -1px;
right: -1px;
bottom: -1px;
left: -1px;
background: red;
z-index: -1;
opacity: .5;
}
button:hover:before {
opacity: .8;
}
button:active:before {
background: orange;
}
<button>Button</button>
It's a bit tricky because using a combination of a rgb background color and opacity sounds like it will work but the opacity will apply to everything inside the element - including the text. there are a number of ways of getting around this though so use a solution that will work for your situation.
Essentially you've got to separate the background element from the rest of the button so that only the background color gets effected by the opacity change on hover.
.my-btn:hover a {
background-color: rgb(255,0,0);
opacity:.5;
}
<div class="my-btn">
<span aria-hidden="true">whatever</span>
<span class="sr-only">whatever</span>
</div>
Here's a demo
Use the opacity attribute:
.my-btn:hover {
opacity: 0;
}
.my-btn:hover {
opacity: 0;
}
<input class="my-btn" type="submit"></input>

Resources