I'm trying to understand the simplest background transition possible using only HTML5 and CSS3. Searching through stackoverflow I've learned it can be easily implemented using external libraries such as jQuery but for this project I've decided not relying on any of those.
Markup
<nav>
<ul>
<li><a id="foobar" href="http://www.google.com/search?q=foobar">Foobar</a></li>
</ul>
</nav>
Styles
body {
background: url('background-default.png'), no-repeat;
}
#foobar a:hover {
background: url('background-hover.png'), no-repeat;
-webkit-transition: // TODO;
-moz-transition: // TODO;
-o-transition: // TODO;
-ms-transition: // TODO;
transition: // TODO;
}
As I mentioned in my comment, you can't transition the background-image property but you can get the sort of effect you're looking for if you're willing to add extra markup and then transition the opacity. So you'll have some markup like this:
<nav>
<ul>
<li>
<img src="no-icon.png">
<img src="yes-icon.png">
<a id="foobar" href="http://www.google.com/search?q=foobar">Foobar</a>
</li>
</ul>
</nav>
Then set the transition on the images, absolute position them (so they'll be like backgrounds), and hide one of them by default (I've left out the vendor extensions for clarity):
nav li img {
position: absolute;
transition-duration: 1.5s;
opacity: 1;
}
nav li img:first-child {
opacity: 0;
}
Then swap the opacity values on li:hover:
nav li:hover img {
opacity: 0;
}
nav li:hover img:first-child {
opacity: 1;
}
Here's a full working example. Not an ideal solution because you have to add extra markup, but it'll work.
Here's an example of the code I use to achieve this. The images are sprites which each contain normal and hover state. The trick is to add the img to both li and a, and to use opacity to change the appearance of the image. You can then use css3 transitions to make this appear smoother.
<ul id="homenav">
<li class="h"><a href="#><span>Home</span></a></li>
<li class="i"><span>Inloggen</span></li>
<li class="v"><span>Voorbeelden</span></li>
</ul>
#homenav li.h, #homenav li.h a {background-image: url('img/btn_home.gif');}
#homenav li.i, #homenav li.i a {background-image: url('img/btn_inloggen.gif');}
#homenav li.v, #homenav li.v a {background-image: url('img/btn_voorbeelden.jpg');}
#homenav li {background-position: 0 170px;}
#homenav li a {background-position: 0 0;}
#homenav li a:hover
{opacity: 0;
-webkit-transition: opacity .8s ease-in;
-moz-transition: opacity .8s ease-in;
-o-transition: opacity .8s ease-in;
transition: opacity .8s ease-in;}
#homenav a {display: block; height: 100%;}
#homenav a span {display: none;}
Related
I'm very new to web dev right now, and I'm currently trying to make an image fade into color upon hovering over it. This is what I've got right now:
html:
<body>
<img src=imgmonochrome.jpg id=img1>
</body>
css:
#img1 {
position: top right;
height:49%;
width:49%;
transition: content 0.5s ease;
}
#img1:hover {
transition: content 0.5s;
content: url('imgcolor.jpg');
}
The image will switch, but will not fade in.
I've looked all over for answers on this, but I can't find any that use just HTML and CSS (cause I'm illiterate in javascript/jQuery ((but going to learn very soon for this very reason)))
Help would be appreciated.
YES, this is possible... But not in the traditional sense.
In order to accomplish this, you'll need to forgo <img />, and instead make use of two images presented with content: url() in :before and :after pseudo-classes. Set the :before to be your starting image, and :after to be your target image. Then set the opacity of :after to 0 by default, and set the two pseudo-elements to sit on top of one another. Finally, set a :hover rule for both :before and :after which toggles their opacity, and use transition: opacity to control the fade.
This can be seen in the following:
* {
margin: 0;
}
.image:before {
content: url("https://via.placeholder.com/150/FF0000/00FFFF");
transition: opacity 0.5s ease;
-webkit-transition: opacity 0.5s ease;
}
.image:after {
position: absolute;
left: 0;
opacity: 0;
content: url("https://via.placeholder.com/150/00FFFF/FF0000");
transition: opacity 0.5s ease;
-webkit-transition: opacity 0.5s ease;
}
.image:hover:after {
opacity: 1;
}
.image:hover:before {
opacity: 0;
}
<div class="image"></div>
Remove content from the transition and use img tag to set image
<img src="imgmonochrome.jpg" id="img1">
#img1 {
position: top right;
height:49%;
width:49%;
transition: 0.5s ease;
}
#img1:hover {
opacity: 0.3;
background: url(imgcolor.jpg);
}
Alternatively,
<img src="imgcolor.jpg" id="img1">
#img1 {
filter: gray;
-webkit-filter: grayscale(1);
-webkit-transition: all .5s ease-in-out;
}
#img1:hover {
filter: none;
-webkit-filter: grayscale(0);
}
I'm trying to make a "fade-in fade-out" effect using the CSS transition. But I can't get this to work with the background image...
The CSS:
.title a {
display: block;
width: 340px;
height: 338px;
color: black;
background: transparent;
/* TRANSITION */
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
transition: background 1s;
}
.title a:hover {
background: transparent;
background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
/* TRANSITION */
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
transition: background 1s;
}
Take a look: http://jsfiddle.net/AK3La/
You can transition background-image. Use the CSS below on the img element:
-webkit-transition: background-image 0.2s ease-in-out;
transition: background-image 0.2s ease-in-out;
This is supported natively by Chrome, Opera and Safari. Firefox hasn't implemented it yet (bugzil.la). Not sure about IE.
The solution (that I found by myself) is a ninja trick, I can offer you two ways:
first you need to make a "container" for the <img>, it will contain normal and hover states at the same time:
<div class="images-container">
<img src="http://lorempixel.com/400/200/animals/9/">
<img src="http://lorempixel.com/400/200/animals/10/">
</div>
with CSS3 selectors http://jsfiddle.net/eD2zL/1/ (if you use this one, "normal" state will be first child your container, or change the nth-child() order)
CSS2 solution http://jsfiddle.net/eD2zL/2/ (differences between are just a few selectors)
Basically, you need to hide "normal" state and show their "hover" when you hover it
and that's it, I hope somebody find it useful.
Unfortunately you can't use transition on background-image, see the w3c list of animatable properties.
You may want to do some tricks with background-position.
I've figured out a solution that worked for me...
If you have a list item (or div) containing only the link, and let's say this is for social links on your page to facebook, twitter, ect. and you're using a sprite image you can do this:
<li id="facebook"></li>
Make the "li"s background your button image
#facebook {
width:30px;
height:30px;
background:url(images/social) no-repeat 0px 0px;
}
Then make the link's background image the hover state of the button. Also add the opacity attribute to this and set it to 0.
#facebook a {
display:inline-block;
background:url(images/social) no-repeat 0px -30px;
opacity:0;
}
Now all you need is "opacity" under "a:hover" and set this to 1.
#facebook a:hover {
opacity:1;
}
Add the opacity transition attributes for each browser to "a" and "a:hover" so the the final css will look something like this:
#facebook {
width:30px;
height:30px;
background:url(images/social) no-repeat 0px 0px;
}
#facebook a {
display:inline-block;
background:url(images/social) no-repeat 0px -30px;
opacity:0;
-webkit-transition: opacity 200ms linear;
-moz-transition: opacity 200ms linear;
-o-transition: opacity 200ms linear;
-ms-transition: opacity 200ms linear;
transition: opacity 200ms linear;
}
#facebook a:hover {
opacity:1;
-webkit-transition: opacity 200ms linear;
-moz-transition: opacity 200ms linear;
-o-transition: opacity 200ms linear;
-ms-transition: opacity 200ms linear;
transition: opacity 200ms linear;
}
If I explained it correctly that should let you have a fading background image button, hope it helps at least!
You can use pseudo element to get the effect you want like I did in that Fiddle.
CSS:
.title a {
display: block;
width: 340px;
height: 338px;
color: black;
position: relative;
}
.title a:after {
background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
content: "";
opacity: 0;
width: inherit;
height: inherit;
position: absolute;
top: 0;
left: 0;
/* TRANSISITION */
transition: opacity 1s ease-in-out;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
}
.title a:hover:after{
opacity: 1;
}
HTML:
<div class="title">
HYPERLINK
</div>
If you can use jQuery, you can try BgSwitcher plugin to switch the background-image with effects, it's very easy to use.
For example :
$('.bgSwitch').bgswitcher({
images: ["style/img/bg0.jpg","style/img/bg1.jpg","style/img/bg2.jpg"],
effect: "fade",
interval: 10000
});
And add your own effect, see adding an effect types
Try this, will make the background animated worked on web but hybrid mobile app
not working
#-webkit-keyframes breath {
0% { background-size: 110% auto; }
50% { background-size: 140% auto; }
100% { background-size: 110% auto; }
}
body {
-webkit-animation: breath 15s linear infinite;
background-image: url(images/login.png);
background-size: cover;
}
Considering background-images can't be animated,
I created a little SCSS mixin allowing to transition between 2 different background-images using pseudo selectors before and after. They are at different z-index layers. The one that is ahead starts with opacity 0 and becomes visible with hover.
You can use it the same approach for creating animations with linear-gradients too.
scss
#mixin bkg-img-transition( $bkg1, $bkg2, $transTime:0.5s ){
position: relative;
z-index: 100;
&:before, &:after {
background-size: cover;
content: '';
display: block;
height: 100%;
position: absolute;
top: 0; left: 0;
width: 100%;
transition: opacity $transTime;
}
&:before {
z-index: -101;
background-image: url("#{$bkg1}");
}
&:after {
z-index: -100;
opacity: 0;
background-image: url("#{$bkg2}");
}
&:hover {
&:after{
opacity: 1;
}
}
}
Now you can simply use it with
#include bkg-img-transition("https://picsum.photos/300/300/?random","https://picsum.photos/g/300/300");
You can check it out here:
https://jsfiddle.net/pablosgpacheco/01rmg0qL/
If animating opacity is not an option, you can also animate background-size.
For example, I used this CSS to set a backgound-image with a delay.
.before {
background-size: 0;
}
.after {
transition: background 0.1s step-end;
background-image: $path-to-image;
background-size: 20px 20px;
}
Salam, this answer works only in Chrome, cause IE and FF support color transition.
There is no need to make your HTML elements opacity:0, cause some times they contain text, and no need to double your elements!.
The question with link to an example in jsfiddle needed a small change, that is to put an empty image in .title a like background:url(link to an empty image); same as you put it in .title a:hover but make it empty image, and the code will work.
.title a {
display: block;
width: 340px;
height: 338px;
color: black;
background: url(https://upload.wikimedia.org/wikipedia/commons/5/59/Empty.png) repeat;
/* TRANSISITION */
transition: background 1s;
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
}
.title a:hover{ background: transparent;
background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
/* TRANSISITION */
transition: background 1s;
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
}
Check this out https://jsfiddle.net/Tobasi/vv8q9hum/
With Chris's inspiring post here:
https://css-tricks.com/different-transitions-for-hover-on-hover-off/
I managed to come up with this:
#banner
{
display:block;
width:100%;
background-repeat:no-repeat;
background-position:center bottom;
background-image:url(../images/image1.jpg);
/* HOVER OFF */
#include transition(background-image 0.5s ease-in-out);
&:hover
{
background-image:url(../images/image2.jpg);
/* HOVER ON */
#include transition(background-image 0.5s ease-in-out);
}
}
This can be achieved with greater cross-browser support than the accepted answer by using pseudo-elements as exemplified by this answer: https://stackoverflow.com/a/19818268/2602816
I was struggling with this for a bit, I first used a stack of images on top of each other and every three seconds, I was trying to animate to the next image in the stack and throwing the current image to the bottom of the stack. At the same time I was using animations as shown above. I couldn't get it to work for the life of me.
You can use this library which allows for **dynamically-resized, slideshow-capable background image ** using jquery-backstretch.
https://github.com/jquery-backstretch/jquery-backstretch
I am trying to create an event with just CSS that will have a DIV (which is coloured white) turn from 0.6 opacity to 1.0 opacity when I hover over a separate div, so much so that when I hover over one div the other looks as if it is faded out.
My code can work if I wanted the div I hover over to fade but I want to hover and change the other div not the one I am hovering over.
HTML
<div id="sell1">
<div class="s1"></div>
</div>
<div id="gap"></div>
<div id="sell2">
<div class="s2"></div>
</div>
CSS
#sell1 {
height:100px;
width:100%;
background-color: rgb(50,70,130);
}
#sell2 {
height:100px;
width:100%;
background-color: rgb(50,70,130);
}
#gap {
height:50px;
background-color:white;
}
.s1, .s2 {
width:100%;
height:247px;
position:absolute;
background:rgba(255, 255, 255, 0.6);
opacity:0;
-webkit-transition: opacity .25s ease;
-moz-transition: opacity .25s ease;
}
#sell2:hover .s1 {
opacity:1;
}
http://jsfiddle.net/UgsyL/186/
So here I want to hover over the "sell2" div and have .s1 turn from 0.6 to 1.0 opacity.
Any help?
With your current setup of HTML, that's impossible. However, as LinkinTED pointed out, it's possible to hover #sell1 and make .s1 fade, by styling #sell1:hover ~ #sell2 .s2 { ... }.
If you need only to hover #sell2 and change .s1, you can switch their places in the HTML, making it:
<div id="sell2">
<div class="s2"></div>
</div>
<div id="gap"></div>
<div id="sell1">
<div class="s1"></div>
</div>
And then style the divs with relative and absolute positioning to be switched, as well as styling the hover with the code provided by LinkinTED.
This isn't THE answer to the question I asked originally but it is a work around I finally figured out that works for what I am wanting to do.
HTML
<ul>
<li><div></div></li>
<br/>
<li><div></div></li>
</ul>
CSS
div {
background-color: rgb(40,80,120);
height: 100px;
width: 200px;
}
ul li {
display: inline-block;
}
ul li div {
opacity: 1;
-webkit-transition: opacity .5s;
-moz-transition: opacity .5s;
transition: opacity .5s;
}
ul:hover li div {
opacity: .5;
}
ul:hover li div:hover {
opacity: 1;
}
http://jsfiddle.net/xbMtN/7/
HTML:
<ul class="nav">
<ul>
<li>Home</li>
<li>A
<ul>
<li>X</li>
<li>Y</li>
<li>Z
</ul>
</li>
</ul>
</ul>
CSS:
.nav ul ul {
position:absolute;
visibility: hidden;
opacity:0;
width:170px;
margin:0;
transition:visibility 0s linear 0.3s, opacity 0.3s linear;
-webkit-transition:visibility 0s linear 0.3s, opacity 0.3s linear;
-moz-transition:visibility 0s linear 0.3s, opacity 0.3s linear;
}
.nav ul li:hover > ul {
visibility: visible;
opacity:1;
}
I want the first level to fade in, on hover on a list item of the main menu, but it just doesn't seem to work. I have spent hours on it and I'm not sure what's really wrong. Any pointers?
If you need to see the complete code: http://paperbird.in/projects/BusinessConclave/index.php
Edit: Ok, you contributed your website, so here's the solution, actually the transition does work, but z-index is causing you an issue there, so it flicks the sub menu instantly.. though it transits, use z-index: 100; for .nav ul li:hover > ul on line 153 in style.css and make sure you remove visibility properties as they are not required.
First of all, your markup is invalid, you cannot nest ul as a direct descendant to ul so nest that in an li and secondly, you cannot transit visibility property, so only use opacity and get rid of the visibility property as well. If you want, you can also use animation-timing-function property with a value of linear for a consistent fadein and fadeout effect.
Demo
.nav ul ul{
position:absolute;
opacity:0;
width:170px;
margin:0;
-webkit-transition:opacity 0.3s linear;
-moz-transition:opacity 0.3s linear;
transition:opacity 0.3s linear;
}
.nav ul li:hover > ul{
opacity:1;
}
And make sure you declare properietary properties before general properties.
My CSS calls for a background image that I want changed on a:hover. The class is working fine with the font color change, but I can't get my image to display anywhere.
<ul class="qualities_cycle">
<a href="http://spielconsulting.com/qualities/transition/" class="cyclehover">
<li class="grid_4">
<div class="title-wrap">
<h3>Partnership Transition</h3>
</div>
<h5>Lorem ipsum dolor sit amet consec</h5>
Seven out of ten Associateships fail - a devastating statistic. Spiel Consulting, however, sees tremendous success with Associateships...
</li>
</a>
</ul>
And here's the CSS
.qualities_cycle {
width:100%;
overflow:hidden;
margin:0;
padding:0;
}
.qualities_cycle li {
padding:0;
background:none;
border:none;
line-height:22px;
}
.qualities_cycle li .title-wrap {
position:relative;
padding:0 90px 0 60px;
}
.qualities_cycle li .icon {
position:absolute;
left:0;
top:0;
}
.qualities_cycle li .title-wrap h3 {
font-weight:normal;
}
.qualities_cycle li .title-wrap h3 a {
color:#0f0f0f;
text-decoration:none;
}
.qualities_cycle li .title-wrap h3 a:hover {
color:#80B34C;
}
.grid_4 {
display:inline;
float: left;
position: relative;
padding: 19px 9px !important;
}
a.cyclehover {
color:#0F0F0F;
background-image:url("http://spielconsulting.com/wp-content/uploads/2011/04/icon1.gif") no-repeat scroll 0 0 transparent;
-o-transition:color .2s ease-out, background 1s ease-in;
-ms-transition:color .2s ease-out, background 1s ease-in;
-moz-transition:color .2s ease-out, background 1s ease-in;
-webkit-transition:color .2s ease-out, background 1s ease-in;
/* ...and now override with proper CSS property */
transition:color .2s ease-out, background 1s ease-in;
}
a.cyclehover:hover {
color: #4C739B;
background-image:url("http://spielconsulting.com/wp-content/uploads/2011/04/icon2.gif") no-repeat scroll 0 0 transparent;
}
a jsfiddle link is here
I'm trying to get three columns in and this is what I have, but the images aren't showing up:
Just change CSS related to a.cyclehover
a.cyclehover {
color: #0F0F0F;
background-image: url("http://spielconsulting.com/wp-content/uploads/2011/04/icon1.gif");
display: block;
float: left;
background-repeat: repeat;
-o-transition: color .2s ease-out, background 1s ease-in;
-ms-transition: color .2s ease-out, background 1s ease-in;
-moz-transition: color .2s ease-out, background 1s ease-in;
-webkit-transition: color .2s ease-out, background 1s ease-in;
transition: color .2s ease-out, background 1s ease-in;
}
After a quick glance, I've spotted these problems in your page:
You're using the background-image CSS property as if it was background.
Inside the <div> contained in the <a> you have floating elements, which are considered to be outside of the normal element flow in your page, so your <div> ends up having a null height: you can "fix" this by adding the overflow: hidden; style to the <div>.
You should not put block elements (such as <div>) inside an <a> at all, that's not valid HTML.
You're trying to apply a CSS transition to the background property, but background is not animatable: http://www.w3.org/TR/css3-transitions/#animatable-properties
In short: rewrite the page, follow some good documentation and use the W3C Markup Validator.
I didn't take a deep look into your code but you're using the background property the wrong way.
Basically, change this:
background-image:url("http://spielconsulting.com/wp-content/uploads/2011/04/icon1.gif") no-repeat scroll 0 0 transparent;
to this:
background:url(http://spielconsulting.com/wp-content/uploads/2011/04/icon1.gif) no-repeat 0 0;
Check if it works... if so, you can add the "scroll" property if it's really necessary. I don't even know what that "transparent" thing is... backgrounds are transparent by default so it shouldn't be necessary. If you need to apply another background-color, do so before the url()...
Btw, this is how you should 'think' background shorthands in CSS (at least is how I use them):
background: color url() repeat fixed left top;
so:
background: #000 url(imgs/logo.png) no-repeat scroll 0 0;
In the example, instead of the #000 color, you could use transparent, but again, it's the default. But use it if you have another rule setting a color and you want it to be transparent.
Also remember that backgrounds can only be applied to "block" elements. If your element is not a block element, set it to, for ex.: display: block; or display: inline-block; set a width and a height to it and you should be good to go.