CSS Transition: Opacity vs changing Background-Color? - css

I am curious if there is an industry standard for transitioning colour since there are multiple ways to accomplish the desired transition effect.
There are multiple ways to make a particular colour brighter or darker to indicate to the user that the element is intractable.
For example, if you have a p tag and you want to add a hover over effect you could:
HTML
<div><p> P tag text </p></div>
CSS v1 using opacity
div {
background-color:black;
}
p {
color: white;
opacity: 0.8;
transition: opacity 0.2s ease-in-out;
}
p:hover {
opacity: 1;
}
CSS v2 using colour
div {
background-color:black;
}
p {
color: #ccc;
transition: color 0.2s ease-in-out;
}
p:hover {
color: #fff;
}
As far I'm aware both methods provide similar results however, I am still curious whether or not there is a correct way to do this kind of thing.

The main thing you should realize is that opacity affects an entire element and all its descendants, whereas color and background-color do not.
In your simple example, white text with reduced opacity on a solid black background looks gray, so the visual effect is basically the same as changing the color from gray to pure white.
But in any more complicated example – say, the background of your paragraph's parent div is an image rather than a solid color, or you're using opacity on an element that contains other elements and not merely on text – what you're gonna end up with is things that truly look see-through. That also may mean that text becomes harder to read.
So the answer is less about there being any particular industry standard and more about choosing the right tool for the job. If you just want to make some text a lighter color, transition color itself. If you want to make things see-through, use opacity.
That's the theory, anyway, but in real life sometimes it's not that clean cut. Maybe a designer gives you a mockup with text that's color: #C44242; opacity: 0.87 on top of a solid-colored background that's background-color: #B48927. You could compute what the opaque version of that text color would be, but it may not be worth your time to do so. The world won't end if you just stick with opacity.

Related

CSS3 Change text opacity without affecting stroke

Have a unique issue here. I'm trying to set some text to completely opaque, while still keeping a visible stroke on the text. I'd like to be able to see through the text as the background is dynamic, so I can't simply set it to the color of its backround.
Here's what I've got, but opacity is overwriting the stroke:
#special {
opacity: 0;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: black;
}
Help appreciated!
The opacity affects all visual properties of the object.
But, what about this?
#special {
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: black;
color: transparent;
}
JsFiddle: http://jsfiddle.net/fdLecLan/2/
About the opacity, the W3schools says:
The opacity-level describes the transparency-level, where 1 is not transparant at all, 0.5 is 50% see-through, and 0 is completely transparent.
So setting it to 0 will make it totally transparent, but is important to remember that it stills stay in the View port, and stills interact with user (So, if it's a button or link, it'll still be clickeable...)

any perfomance gain when specifying property to transition instead of all [duplicate]

I have a question about rendering speed for the css3 transition property.
Suppose I have a number of elements:
div, span, a {transition: all}
div {margin: 2px}
span {opacity: .5}
a:hover {background-position: left top}
div:hover {margin: -100px}
span:hover {opacity: 1}
a:hover {background-position: -5px top}
It's much more efficient to target all of the transitions for all of those elements using one declaration div, span, a {transition: all}. But my question is: would it be "faster" in terms of the smoothness and quickness of the animation rendering to target each element's specific transition property? For example:
div {margin: 2px; transition: margin .2s ease-in}
span {opacity: .5; transition: opacity .2s ease-in}
a {background-position: left top; transition: background .2s ease-in}
div:hover {margin: -100px}
span:hover {opacity: 1}
a:hover {background-position: -5px top}
My logic in asking this is that if the css "engine" has to search for "all" transition properties even if there is just one single property for an element, that it might slow things down.
Does anyone know if that's the case? Thanks!
Yes, using transition: all could cause major drawbacks in performance. There can be a lot of cases where the browser would look if it needs to make a transition, even if user won't see it, like the color changes, dimension changes etc.
The simplest example I can think of is this: http://dabblet.com/gist/1657661 — try to change the zoom level or the font's size and you'll see that everything become animated.Of course there couldn't be a lot of such user interactions, but there could be some interface changes that can cause the reflow and repaints in some blocks, that could tell the browser to try and animate those changes.
So, in general, it's recommended that you won't use the transition: all and would use the direct transitions instead.
There are some other things that can go wrong with the all transitions, like the splash of animation on page load, where it would at first render the initial styles for blocks and then apply the style with an animation. In a lot of cases it wouldn't be the thing that you want :)
I've been using all for cases where I needed to animate more than one rule. For example, if I wanted to change the color & background-color on :hover.
But it turns out that you can target more than one rule for transitions, so you never need to resort to the all setting.
.nav a {
transition: color .2s, text-shadow .2s;
}

Smooth color transition with LESS

I'm using LESS to style a web page (with Bootstrap). What I'd like to do is add a smooth color transition when I hover my mouse over an element. Doesn't this functionality come right out of the box in LESS?
I'm trying to do it like this:
.list-group {
.list-group-item:hover {
background: fadein(#cn-sidemenu-hover-bg, 100%);
}
.list-group-item {
background: #cn-sidemenu-bg;
color: #fff;
}
}
But this has no color animation. But the name kinda implies to me that this should do some sort of color animation?
Otherwise I don't see any difference between fadein and lighten..
How can I do a smooth color transition with LESS?
You will need to add a transition attribute to the .list-group-item class like:
.list-group-item{
background: #cn-sidemenu-bg;
color: #fff;
transition: background 500ms;
}
Transition tells the browser to interpolate between two defined attributes. fadein and lighten are LESS specific functions, that only process the color value resulting in a fixed color value.
i.e. this
lighten(#aa0000, 5) would result in the color value #c30000;
fadein does the same thing of color manipulation, but edits the opacity value.

Font-Weight CSS Transition in Chrome

Trying to get font-weight to gracefully transition from '400' to '600' using CSS but it doesn't appear to be working in Chrome. Is this a known bug or am I doing something wrong?
Check the Fiddle here for an example
The problem is that font weights, when represented numerically, must be a multiple of 100. To animate between 400 and 600, the font would change from 400 to 500 to 600 (3 'frames', if you like) and wouldn't look very smooth. An animation wouldn't increment the weight by 1 each time (400, 401, 402...) it would increment the weight by 100 (400, 500, 600). If your animation lasted 2 seconds, after 1 second the weight would suddenly become 500, and after 2 seconds the weight would suddenly become 600; there are no in-between variations.
A further problem with what you're attempting here is that the font you're using (or JSFiddle's default, at least) doesn't have anything different for font-weight:500, meaning it defaults to 400:
<p style="font-weight:400;">a - 400, normal</p>
<p style="font-weight:500;">a - 500 (no support, defaults to 400)</p>
<p style="font-weight:600;">a - 600 (bold)</p>
<p style="font-weight:650;">a - 650 (not valid, defaults to 400)</p>
http://jsfiddle.net/r4gDh/6/
Numeric font weights for fonts that provide more than just normal and bold. If the exact weight given is unavailable, then 600-900 use the closest available darker weight (or, if there is none, the closest available lighter weight), and 100-500 use the closest available lighter weight (or, if there is none, the closest available darker weight). This means that for fonts that provide only normal and bold, 100-500 are normal, and 600-900 are bold.
https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
This basically means that you can't smoothly animate font-weight. Even if you had support for all weights between 100 and 900 the change wouldn't be pleasant and there would be a dramatic change between 500 and 600 (where lighter weight meets darker weight).
I came here to find out the answer myself for how to transition font weight, and was disappointed when I read the approved answer above saying that it can't be done (or at least not very well).
With font-weight animation unavailable, I decided to try another effect, which actually gives you a font-weight effect... which I didn't even think would work for this type of transition.
Here is how to make the weight grow:
.weightGrow:hover {
text-shadow:
-1px -1px 0 #2DD785,
1px -1px 0 #2DD785,
-1px 1px 0 #2DD785,
1px 1px 0 #2DD785;
-webkit-transition: all .5s;
-moz-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;
}
Perfectly smooth and exactly what I was looking for when I first arrived on this page. Hope it helps someone.
Font-weight animation is currently not supported in Chrome and IE-10 based on numerous tests. This may change in the future.
Fonts are not simple vector image collections (that's why svg fonts never took off). Opentype fonts include all kinds of magic to clamp fonts to the pixel grid, which makes it unrealistic to expect a font family to ever include every possible weight value.
Because fonts are not simple vector image collections they will also never resize linearly – there will be bumps to take the pixel grid into account.
This Google whitepaper explains why linear resizing does not work for text on current screens
https://docs.google.com/document/d/1wpzgGMqXgit6FBVaO76epnnFC_rQPdVKswrDQWyqO1M/edit
which is why no browser will attempt it and they will all rely on pre-computed font weights.
That may change in a decade when retina displays are the lowest common denominator but current font tech targets current screens.
This Microsoft whitepaper documents some standard font weight values
http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-components-postattachments/00-02-24-90-36/WPF-Font-Selection-Model.pdf
(but just because they are documented does not mean the number of fonts that actually include all of them is not quite small)
You can probably achieve the effect you want with an svg font and some javascript. The svg font will be crap for text use though.
I seem to have obtained a "font-weight" transition effect accidentally, by doing a quick color transition (light gray to dark blue) at the same time.
Although there is no direct way to get the font-weight to smoothly transition, I have found a way to do this indirectly (although with some limitations).
In essence you can simply use one of the pseudo elements in order to make a mirror copy of the element whom font you want to transition to bold, where the font-weight on the pseudo element is bold and the opacity is 0. And on hover simply transition the pseudo element's opacity and that does the trick with a very smooth transition.
You can see a demo here:
http://jsfiddle.net/r4gDh/45/
HTML:
<div class="element" data-text="text will turn to bold on hover">
text will turn to bold on hover
</div>
In the HTML you can already see one of the limitations, because we are using pseudo elements we need to pass the contents of the element as an attribute as well, so the content is duplicated.
CSS:
.element,
.element::before {
background: red;
font-weight:normal;
font-size:40px;
text-align:center;
display: inline-block;
padding: 0px 30px 0px 30px;
position: relative;
top: 0;
left: 0;
}
.element::before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0;
content: attr(data-text);
opacity: 0;
font-weight: bold;
transition: all 1s linear;
}
.element:hover::before {
opacity: 1;
}
The second limitation comes from the nature of the technique, namely because you are simply overlaying the pseudo element over the original, then the element needs to have a solid background or this will not work, because the original element will remain visible in the background.
One thing you should really keep an eye on is that the pseudo element and the original element have the same dimensions, to this end, in the demo, I've removed the padding on the pseudo element, so you may need to do something similar.
As you can see, this way of getting the font-weight transition is not without it's problems and far from ideal, but this is the best I can currently think of and in limited cases like for buttons and what not this is quite useful and if done correctly will look decent even in legacy browsers.
Smooth font-weight transitions and animations are possible using variable fonts which are not limited to increments of 100. More info on variable fonts here: https://web.dev/variable-fonts/
Try this snippet with eg. https://fonts.google.com/specimen/Raleway
#font-face {
font-family: 'Raleway Flex';
src: url('Raleway-VariableFont_wght.ttf');
font-weight: 100 900;
}
h1 {
font-family: 'Raleway Flex', sans-serif;
animation: example 1s linear 0s infinite alternate both;
}
#keyframes example {
from {
font-weight: 100;
}
to {
font-weight: 900;
}
}
<h1>HELLO</h1>
<p>I look way smoother if you use a variable font.</p>
I've tweaked #Idra's fiddle to make the normal to bold transition a bit smoother. Here's the fiddle: http://jsfiddle.net/y7rLwx95/
Changes... Since the text width will get wider when going to bold, I've added an initial "stretch" transition by increasing the letter spacing:
.element:hover {
letter-spacing: 0.9px;
transition: all .3s linear;
}
Then delayed the fading in of the bold ::before element:
.element:hover::before {
opacity: 1;
transition-delay: .2s
}
Also some additional tweaks here:
.element::before {
transition: all .3s linear; /* replace */
letter-spacing: 0; /* additional */
}
The transition timing is just whatever feels right to me. The original idea #Idra posted is significant to me. I accept that fact that the widths should be different between normal and bold, as that's the intent of different font weights. So really the challenge, IMHO, is to figure out how to go between the 2 looks in a smooth, no jarring way. This seems to be the best solution so far I've found.

CSS3 Transitions

I want to change the background color of the page when one hovers over a button/div tag using only CSS3 transitions. I want the color to come gradually and hence would like to use a transition effect, but I don't know how to relate the background color of the page to a hover event on a div. Can someone please help me with my code ? Thank You
This is not currently possible in CSS3.
In the future (CSS4?), you'll be able to do it as follows:
body {
background-color: red;
transition: background-color 1s ease;
}
$body #theButton:hover {
background-color: green;
}
Note the $ in the second selector; It indicates which element the CSS block applies to. Unfortunately, there's not even a single implementation of this yet, so you'll have to resort to Javascript (which I assume you know how to do. If not, just ask).
Update (using jQuery):
CSS:
​body {
background: red;
transition: background-color 1s ease;
}
body.hover {
background: green;
}
Javascript:
​$('#theButton').hover(function(){
$('body').addClass('hover');
}, function(){
$('body').removeClass('hover');
});​​​​​​​​
Here's the fiddle: http://jsfiddle.net/mWY88/1/
For maximum efficiency, you should cache your selectors.
In fact, you can change the body background-color very easily with CSS3 transition animation like I'm doing it here. I got the logic from here.

Resources