CSS Translate - Unexpected behaviour - css

I wanted a button to move down a few pixels on hover, but it comes back up again. Shouldn't it stay where it is while you're still hovering on it?
Email Me
.btn {background: #2ecc71; padding: .5em 1em; border-radius: 3px; color:white; font-size: 1.5em; text-shadow:2px 2px 2px #178345; box-shadow: 0px 1px 1px #21a559; transition: transform 0.5s ease 0s;}
.btn:hover {background: #28b865; transform: translate(0px, 3px);}
http://codepen.io/anon/pen/zICBw

The problem is inline element can't be transformed properly. If you set the transform right in normal state, you'll see the transform takes no effect. However it does have a little effect on animation, maybe because while animating, the element's display becomes inline-block (or block in some other cases, at least while being animated, the transform can take effect). After the animation completes, it returns back to inline. So the button's position is set back like as the translate transform has no effect.
Your button is actually an a element, which has inline display by default. You can simply change its display to inline-block or block and it works OK:
.btn {
/* ... */
display:inline-block;
}
Updated demo.

Why not simply transition top? You'll need to position the element, but it will accomplish the same without the reversion.
The problem with transitioning on transform is you change the plane the element occupies, which causes the hover state to no longer trigger. One way around this is to also apply a base transform state to the element.
Demo Fiddle
.btn {
background: #2ecc71;
padding: .5em 1em;
border-radius: 3px;
color:white;
font-size: 1.5em;
text-shadow:2px 2px 2px #178345;
box-shadow: 0 1px 1px #21a559;
transition: top .5s ease;
top:0px;
position:relative;
}
.btn:hover {
background: #28b865;
top:3px;
}

Related

Applying webkit transitions to span classes?

I've seen a similar question asked, but the solutions wouldn't work for how I was using the span classes. In effect, I'm using the span classes as alternate text for a hover. I'd like to ease in / ease out the classes on hover, but I can't figure out where to apply the webkit or what I'm doing wrong.
HTML
<div class="mdmg2"><span class="alias">name</span> <span class="infor">age / tz / pm</span></div>
CSS
.mdmg2 { text-transform: lowercase; color: #fff; text-align: left; font-size: 40px; text-shadow: 1px 1px 0px black, 1px 1px 0px white, 1px 1px 0px black; }
.mdmg2 .infor { display: none; }
.mdmg2:hover .alias { display: none; }
.mdmg2:hover .infor { display: inline; font-size: 30px; text-transform: uppercase; font-family: montserrat; position: relative; top: -10px; }
Interpretation
As I understand it, you want .alias to be shown when .mdmg2 is not hovered, and for .infor to be shown when it is hovered. You want to fade in-between the two.
Your Problem
You cannot animate the display property, and thus if you want to fade content it is not going to be suitable. However, there is a CSS property called opacity. This can be set to any decimal between 0 and 1, which corresponds to a percentage value of how opaque the element is (i.e. how transparent it is).
This property can be animated, so we change the display styles to use opacity instead, and add in the proper code to perform the animation. Although OP asked for webkit transitions, there is no vendor prefix for transition (see http://caniuse.com/#search=transition), so the property is just transition. You can read about it's syntax and how it works here.
Now, there is an animation on-hover, but unlike display, using opacity the old object still takes up space on the page; i.e. the two spans are not in the same space. This is obviously not right, and so to fix this, we set a width on .alias (100px). This ensures that .alias will always take up 100px, so we can move .infor to 100px to the right to ensure that the two elements line up.
Solution
Thus, the complete solution to your issue is:
.mdmg2 {
text-transform: lowercase;
color: #fff;
text-align: left;
font-size: 40px;
text-shadow: 1px 1px 0px black, 1px 1px 0px white, 1px 1px 0px black;
position:relative;
}
.mdmg2 .infor {
opacity:0;
font-size: 30px;
text-transform: uppercase;
font-family: montserrat;
transition:opacity 0.5s;
position:relative;
left:-100px;
}
.mdmg2 .alias {
opacity:1;
transition:opacity 0.5s;
width:100px;
}
.mdmg2:hover .infor {
opacity:1;
}
.mdmg2:hover .alias {
opacity:0;
}
<div class="mdmg2"><span class="alias">name</span> <span class="infor">age / tz / pm</span></div>

Don't affect positioning of other elements on border-width changes

I'd like to change border-width of a circle on hover without affecting the positioning of other elements.
It will be more clear with this jsFiddle.
HTML
<span class="menu"><i class="cercle"></i>Foo</span>
<span class="menu"><i class="cercle"></i>Bar</span>
CSS
.menu{
margin-right: 10px;
cursor: pointer
}
.cercle{
border-radius: 16px;
margin-right: 5px;
vertical-align: middle;
width: 16px;
height:16px;
display:inline-block;
border: 5px solid #ff9c08
}
.menu:hover i{
border-width: 3px;
transition:border-width .1s
}
There are a couple of different ways you can go about achieving the effect you desire.
1. Using box-sizing: border-box:
Normally, neighbouring elements are affected by the changing an element's border-width property, because the elements are relatively positioned and the space each one occupies changes when the border-width changes. Using box-sizing: border-box ensures the width of the border is included in the dimensions of the element.
.cercle {
box-sizing: border-box;
}
2. Using box-shadow:
An alternative would be to use box-shadow property, instead, to imitate the visual appearance of a border but without its particular behaviour. The shadow of an element doesn't affect neighbouring elements when modified, so it's another good option to consider when trying to achieve the effect you desire.
.cercle {
box-shadow: inset 0 0 0 4px #ff9c08;
}
.menu:hover > .cercle {
box-shadow: inset 0 0 0 2px #ff9c08;
}
Check out more about the browser compatibility of box-sizing and box-shadow to see which suits you better. An updated version of your jsfiddle can be found here and a snippet just below.
Snippet:
.menu {
margin-right: 10px;
cursor: pointer;
}
.cercle {
width: 16px;
height: 16px;
display: inline-block;
margin-right: 5px;
vertical-align: middle;
border-radius: 16px;
}
#ex1 .cercle {
border: 4px solid #ff9c08;
box-sizing: border-box;
}
#ex1 .menu:hover i {
border-width: 2px;
transition: border-width .1s;
}
#ex2 .cercle {
box-shadow: inset 0 0 0 4px #ff9c08;
}
#ex2 .menu:hover .cercle {
box-shadow: inset 0 0 0 2px #ff9c08;
transition: box-shadow .1s;
}
<div id = "ex1">
<span class="menu"><i class="cercle"></i>Foo</span>
<span class="menu"><i class="cercle"></i>Bar</span>
</div>
<br>
<div id = "ex2">
<span class="menu"><i class="cercle"></i>Foo</span>
<span class="menu"><i class="cercle"></i>Bar</span>
</div>
This is not possible without having a border already on the element as adding a border would increase the width and height of the element. The technique I prefer is to have a transparent border on non-hover state to begin with and change the colour on hover.
.menu {
border: 3px solid rgba(0,0,0,0);
}
.menu:hover {
border-color: black;
}
This actually is possible, with box-sizing.
Setting .cercle { box-sizing: border-box; } means that the width and height of the .cercle elements includes the size of the border.
As such, the size of the .cercles will shrink with box-sizing: border-box, but that's an easy fix: just up the height and width from 16px to 21px (a change of 5px, since 5px was the size of the border).
Hopefully I explained how this works okay!
See this jsfiddle for functioning code:
https://jsfiddle.net/xhanrkzy/3/
I would assume you wanted to scale it down.
I used the transform property to do this:
.menu:hover i {
/* border-width: 3px; */
transform: scale(0.95);
transition: border-width .1s
}
In general "box-sizing: border-box" is a great simple solution. Note you can set it to apply to every element by default in your style-sheet. Here's a nice article about it: https://css-tricks.com/box-sizing/ .
Be aware that using border-box and changing the border-width means there is less space inside the circle etc. That is because the border "grows inwards" when using border-box. Therefore changing the border-width can affect the position of elements INSIDE the DOM-element whose border-width you are changing. Whether you consider those to be "other elements" (as per your question) is a matter of semantics.

CSS transition not working when mouse moved off link

im having some troubles with my CSS, i have a button i made and i have given it some CSS to add a color changing effect with webkit transition, the color change works on hover but when mouse is taken off button it wont show effect of it returning to how it was before, heres my css
.button-blue{
border: 1px solid #00B7EF;
border-radius: 5px;
color: #00B7EF !important;
background-color: transparent;
-webkit-transition-property: background-color, color;
-webkit-transition-duration: 0.5s;
webkit-property: background-color, color;
webkit-duration: 0.5s;
}
.button-blue:hover {
border: 1px solid #00B7EF;
border-radius: 5px;
color: white !important;
background-color: #00B7EF;
-webkit-transition-property: background-color, color;
-webkit-transition-duration: 0.5s;
webkit-property: background-color, color;
webkit-duration: 0.5s;
}
You already have transition properties for your href stated previously so just state it once with your href before and remove the transition properties from your button so your css would look like the following:
Working fiddle Fiddle
.navigation-bar ul li a {
color: #333333;
text-decoration: none;
font-family: 'Roboto', sans-serif;
font-size: 19px;
font-weight: 400;
font-style: bold;
padding: 5px 5px 10px 10px;
-webkit-transition-property: background-color, color;
-webkit-transition-duration: 0.5s;
webkit-property: background-color, color;
webkit-duration: 0.5s;
}
.button-blue{
border: 1px solid #00B7EF;
border-radius: 5px;
color: #00B7EF !important;
background-color: transparent;
}
.button-blue:hover {
border: 1px solid #00B7EF;
border-radius: 5px;
color: white !important;
background-color: #00B7EF;
}
webkit-property and webkit-duration aren't CSS properties.
The correct syntax is transition-property and
transition-duration.
-webkit- is only a vendor prefix for CSS features on Google Chrome
and newer versions of Opera.
In pseudoclasses as :hover state, you only have to declare
properties that you will change, isn't necessary repeat already
declared ones. So, border-radius is out (unless you
want to change it).
You have to set the transition in the default state. If you declare
again on :hover state, you are creating a second instance for the
transition, that's why you got this animation on your button.
You already have declared a transition in .navigation-bar ul li a (And have a transition only for color, not background).
So, now you have a problem with specificity, because targeting a parent class and then directly targeting to an HTML
element in CSS has more priority than targeting only a class
(You can check it here).
If all of your a element in your .navigation-bar will have
the same transition, you can set it here. (Not ideal, but it works
cleaner and will be less changes.)
You also need to add a transition for background. This doesn't alter
the rest of your links, because if you don't set a background in
hover (or focus) state, it will not change.
And obviously, you have to remove the transition from
.button-blue, because you will not use it anymore (It would be
repetitive).
Try to modularise more your CSS (don't repeat yourself). You
can learn more searching for BEM, OOCSS or SMACSS
(It's a matter of taste)

How do I remove this ugly border created inset shadow?

How do I remove this ugly border created by a background totally overlapped by a inset shadow? Well, that was the idea anyway.
circle {
display:block;
text-decoration:none;
border-radius:50%;
width:100px;
height: 100px;
background: black;
text-align:center;
transition: all 0.8s ease-out;
box-shadow:inset 0px 0px 0px 50px #ffd300;
font-size: 0;
z-index: -1;
border: 10px solid #ffd300;
}
.circle:hover {
box-shadow:inset 0px 0px 0px 0px #ffd300;
transition: all 0.2s ease-out;
}
Code snippet over at Codepen
There is no solution to the actual rendering. (See below the solution for the explanation).
On the contrary, I've played and found a fix for you, which might do the exact thing, by placing an :after pseudo element to mimic the animation exactly as you want it to be.
Click on the "Run code snippet" button below to see if this is exactly what you want.
.circle {
display:block;
text-decoration:none;
border-radius:50%;
width:120px;
height: 120px;
background: #ffd300;
text-align:center;
transition: all 0.8s ease-out;
font-size: 0;
z-index: -1;
}
.circle:before {
display:block;
content:'';
position:absolute;
background:black;
width:0px;
height:0px;
border-radius:50%;
top:68px;
left:68px;
transition: all 0.2s ease-out;
overflow:hidden;
z-index: 0;
}
.circle:hover:before {
width:100px;
height:100px;
top:18px;
left:18px;
font-size: 48px;
}
.circle:after {
display:block;
position:absolute;
font-size: 48px;
line-height: 90px;
color: black;
transition: color 0.2s ease-out;
content: "J";
z-index: 1;
top:18px;
left:58px;
}
.circle:hover:after {
color: white;
transition: color 0.1s ease-out;
}
<a class="circle" href="#">Click</a>
Explanation to the problem
I've pasted two images of how they are rendered in Webkit (Chrome) and Gecko (Firefox). The shadow is getting pixelated along the edges if it is curved. The same phenomena also happens while drawing a curve.
Image 1, ChromeIt is a 500px x 500px of the same code that you used, just to magnify the effect that we are talking about. You can see those weird ugly border in a better view. Now, try reducing border-radius:50%; to a 20%, 10% or 0%, you will slowly see those ugly marks disappearing. As pixels are square themselves, it renders perfectly in case of a rectangular shape / with straight line edges.
Image 2, FirefoxIn the second image, you can see how Firefox renders the same object (500px x 500px), and adds a secondary unknown border along the outside edge of the circle, which is actually the background:black, going out of the 10px border as well (proof: Change the background to #ffd300 and it will disappear).
To conclude, this aliasing phenomenon is a rendering issue currently for both the major browser engines, though its minimized in actual rendering of the circular object itself, but its more prominent in case of shadows or other things which blurs / blends with other colors. It is not a problem with your code though.
The shape has a background color of black, a 10px outside border of yellow, and a 50px inside border of yellow. This seems to be so that when you hover, it will change the inside of the circle to red.
To get rid of the little sliver completely, you could just change .circle's background to #ffd300 (or whatever).
This breaks the animation, however, so you might want to add background:black to .circle:hover.
You can change your CSS to this:
.circle {
display:block;
text-decoration:none;
border-radius:50%;
width:100px;
height: 100px;
background: #ffd300;
text-align:center;
transition: all 0.8s ease-out;
box-shadow:inset 0px 0px 0px 50px #ffd300;
font-size: 0;
z-index: -1;
border: 10px solid #ffd300;
}
.circle:hover {
box-shadow:none;
background: black;
transition: all 0.2s ease-out;
}
Basically, move the back background to hover state and get rid of the box-shadow. Of course you'll have the border on hover, because it goes with your approach, but at least you won't have the border on default state.
Remember that you can use multiple box-shadows by simply separating them with a comma, but either way, no matter how many you add, you will have this border because the border-radius:50% will add it. For reference, try taking the border-radius definition out and you'll see that border disappear.
In short: the only way to get rid of that border at all times, is to use 2 elements: an outer div with background color #ffd300 and an inner div with background color #000 and the J, otherwise you'll have that border, it's just how CSS works
if you add to the CSS a border-width: 0px;. See http://www.w3schools.com/cssref/pr_border-width.asp

Is CSS3 Transform on Firefox 3.6 stable?

I implemented a CSS3 transform of an image where I scale and translate it. When I hover over the image to transform the resulting image will sometimes flash or not appear. I have to move the mouse around a bit to get it to stick. Is it a problem with my code or the implementation in Firefox 3.6?
html:
<a class="image-transform" href="#" title="William and Catherine"><img src="images/William_Walter_and_Catherine_Rowe.jpg" alt="William Walter and Catherine Rowe"/></a>
css:
.image-transform img
{
float:right;
width: 75px;
background-color: #ffffff;
margin: 1em 1em 1em 1em;
padding: 3px;
border: solid 1px;
-moz-box-shadow: 5px 5px 5px #888;
-o-box-shadow: 5px 5px 5px #888;
-webkit-box-shadow: 5px 5px 5px #888;
box-shadow: 5px 5px 5px #888;
-moz-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
.image-transform:hover img
{
/* width: 300px;*/
-moz-transform: scale(4) translate(-60px);
-webkit-transform: scale(4) translate(-60px);
-o-transform: scale(4) translate(-60px);
transform: scale(4) translate(-60px);
}
This production page is at: http://www.amcolan.info/Rowe/rowe.php. It's the only small photo on the right margin. I've used a javascript solution on another page that works well, but I thought I'd give CSS3 a try.
Thanks for any help.
The reason is really very simple. Have a look at this image:
See, when you hover over the element, the :hover selector takes effect, and it expands and translates, thus moving away from your mouse. Now that the element is not under your mouse, the :hover selector won't take effect, and the element shifts back into the original position, under your mouse. The cycle then repeats.
Now, CSS transitions are not supported in Firefox 3.6, so this happens instantaneously, or as fast as the browser can repaint the screen, so it appears to 'flicker' or 'flash'.
The solution is to make sure that the element is always under the mouse during all parts of the animation, or alternatively, use JavaScript, from where you can use events and queues to gain more fine grained control over the animation.

Resources