Transition for moving objects with position: fixed? - css

This seems like it should be a simple problem, but I'm by no means a CSS expert, and I've been beating my head against the wall trying to figure it out. So I've got a ContentHeader element, and when the user scrolls down past a certain point, I want it to slide up to cover the NavigationHeader element. I'm changing the position of ContentHeader by changing the className property from "content-header" to "content-header top", which works, but ContentHeader just jumps into the new position instead of transitioning smoothly. This is the CSS I'm using currently:
.content-header {
position: fixed;
top: 50;
width: inherit;
z-index: 1030;
padding: 12px 15px 12px 15px;
transition: top 1s linear;
}
.content-header.top {
top: 0;
}
If you need to see the JavaScript, let me know and I can add that as well, but it's basically just doing ...
<section className={className} ...
... where the value of className would vary depending on where ContentHeader should be positioned. I thought maybe the problem was that this is happening inside a React render block and that was skipping the transition, but I tried changing the class with an onClick event that wouldn't force a re-render, and the results were the same. If anyone could help, I'd appreciate it!

You're missing px on your top value, which should read top: 50px;
$('button').on('click', function() {
$('h1').toggleClass('top');
})
.content-header {
position: fixed;
top: 50px;
width: inherit;
z-index: 1030;
padding: 12px 15px 12px 15px;
transition: top 1s linear;
}
.content-header.top {
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 class="content-header">header</h1>
<button>click</button>
That said, I would use transform: translateY(); instead of top because that's more performant. Using a transition or animation with transform get GPU acceleration, where transitioning top does not.
$('button').on('click', function() {
$('h1').toggleClass('top');
})
.content-header {
position: fixed;
transform: translateY(50px);
width: inherit;
z-index: 1030;
padding: 12px 15px 12px 15px;
transition: transform 1s linear;
}
.content-header.top {
transform: translateY(0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 class="content-header">header</h1>
<button>click</button>

Try giving the initial top value a unit, for example: top: 50px.
.content-header {
position: fixed;
top: 50px; // add `px` unit here
width: inherit;
z-index: 1030;
padding: 12px 15px 12px 15px;
transition: top 1s linear;
}

Related

Hover underline effect with Elementor CSS

I have been hitting my head against a brickwall with this issue.
I have tried using this line of code to create an underline on hover effect with CSS using Elementor. I've tried it with a button widget and a Text Editor widget but can't seem to get it to work at all. What am I missing?
Any help would be really helpful.
Thanks
:
.underline {
display: inline;
position: relative;
overflow: hidden;
}
.underline:after {
content: "";
position: absolute;
z-index: -1;
left: 0;
right: 100%;
bottom: -5px;
background: #000;
height: 4px;
transition-property: left right;
transition-duration: 0.3s;
transition-timing-function: ease-out;
}
.underline:hover:after,
.underline:focus:after,
.underline:active:after {
right: 0;
}
Your code almost works - the problem is the transition-property. You have left right which is not legal CSS. And in fact you only want to transition the right property, the underline stays anchored at the left side.
.underline {
display: inline;
position: relative;
overflow: hidden;
}
.underline::after {
content: "";
position: absolute;
z-index: -1;
left: 0;
right: 100%;
bottom: -5px;
background: #000;
height: 4px;
transition-property: right;
transition-duration: 0.3s;
transition-timing-function: ease-out;
}
.underline:hover::after,
.underline:focus:after,
.underline:active:after {
right: 0;
}
<div class="underline">Hover over me</div>
It can be helpful to run your code through the relvant validator. In this case I used the W3C CSS validator which picked up the error.
Although you can transition (animate) the right property as you have done it is often more performant (in CPU/GPU usage sense) to use transforms such as scale or translate to shrink/grow or move things.

How can i fixed safari sub-pixel bug on elements with overflow: hidden?

I'm trying to create a box with label on left top angle. This label must slide on mouse over.
When I hover on this box In Safari Browser (Mac OS El Capitan) I watch the following bug: http://newsletters.loginov.biz/1.png
When the transition is complete yellow label becomes ok (clipping is well).
NB! I discovered that this happens when the viewport width is odd. (You can resize browser step by step to see this problem).
Any ideas?
.box {
position: relative;
overflow: hidden;
left: 50%;
margin-left: -100px;
width: 200px;
height: 200px;
background: #212121;
box-shadow: 0 0 8px rgba(0,0,0,.13);
-webkit-transition: box-shadow 250ms;
transition: box-shadow 250ms;
}
.box:after {
position: absolute;
z-index: 1;
top: 0;
right: 0;
border-left: 60px solid transparent;
border-top: 120px solid #ffcc32;
content: '';
-webkit-transform: translate(30px, -60px);
transform: translate(30px, -60px);
-webkit-transition: transform 250ms;
transition: transform 250ms;
}
.box:hover {
box-shadow: 0 0 45px rgba(0,0,0,.35);
}
.box:hover:after {
-webkit-transform: none;
transform: none;
}
<div class="box">
<img src="http://s.appleinsider.ru/2016/06/macOS-Sierra-Wallpaper-iPhone-Plus-Wallpaper.jpg" alt="test img" />
</div>
I know, this is not an elegant solution, but helped me with exactly the same problem.
In my case there were multiple elements in row and issue was reproduced when wrapper element was centered. So when wrapper has odd width while viewport has odd width too it can't be perfectly centrified in Safari (the same for even width). So your wrapper had to have an opposite fold.
JQuery in my solution is for fast add/remove class - you can use your own methods.
var $wrapper = $('.wrapper'), fixSafariSubpixelDelay;
function fixSafariSubpixel() {
clearTimeout(fixSafariSubpixelDelay);
fixSafariSubpixelDelay = setTimeout(function() {
if (window.innerWidth % 2 == 0)
$wrapper.removeClass('even').addClass('odd');
else
$wrapper.removeClass('odd').addClass('even');
}, 100);
};
window.addEventListener('resize', fixSafariSubpixelDelay);

img not displaying properly after closing bootstrap modal

I'm trying to build a gallery where every image has a hover effect (this one). When I jhover the image and click the link inside , a bootstrap modal opens showing some content.
Until here works fine, however, when I close this modal, the image is not displaying properly in the main page. You can see my problem here:
http://www.bootply.com/90dGFlCrxI
Can anyone explain me what am I doing wrong?
Thanks very much guys!
The issue seems be the
overflow: hidden;
in this css rule:
.effect figure {
margin: 0;
position: relative;
/*overflow: hidden;*/
text-align: left;
}
if you remove the issue is fixed.
another work around:
.effect figcaption {
position: absolute;
width: 100%;
left: 0;
padding: 7px;
background: #26BC8A;
color: #ed4e6e;
height: 50px;
top: auto;
bottom: 0;
opacity: 0;
/* transform: translateY(100%); */
/* transition: transform 0.4s, opacity 0.1s 0.3s; */
}
the translateY is not working as expected.

Jagged "border" showing due to background colour on wrapper element with border-radius: 50%;

As I was in the process of trying to make an animated figure (transitions on hover), I found out that the background of my <figure> is showing near the edges when I apply border-radius: 50% to it, even though my image should be taking up all available space.
For a quick demo that illustrates the problem, please look at http://codepen.io/anon/pen/KwMMKz
HTML
<figure>
<img src="http://placehold.it/400x400" alt>
<figcaption>Demo</figcaption>
</figure>
CSS
figure {
background-color: red;
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
position: relative; /* For caption */
}
img {
border-radius: 50%; /* Forced on image for smooth transition */
width: 100%;
transition: opacity 1s ease-out;
}
figcaption {
position: absolute;
top: 100%;
left: 0;
width: 100%;
color: hotpink;
text-align: center;
transition: top 1s ease-out;
}
figure:hover img {
opacity: 0;
}
figure:hover figcaption {
top: 50%;
}
Please note: I know that placing the background-color on figure:hover is a work-around, but I am more interested in the reason why this "jagged border"-like look is appearing.
My guess is that it has to do with AA rendering (or something related) of the browser and that it treats theĀ <figure> element differently than a media element such as <img>, but I can't find any proof of this online. Is this a bug, is it a "feature", or is it something I can actually fix?
Lastly, I also know that I could have used transform: translateY(); here for the animation, but that's not part of my question so please don't provide it as an answer.
UPDATE 17/12 14:03
It appears that this issue is not exclusive to border-radius: 50%. The issue can occur when any wrapping element uses border-radius in combination with overflow: hidden, when the wrapper contains content that is equal or bigger than the wrapper's dimensions.
UPDATE 17/12 14:14
Neither the usage of overflow: hidden on the wrapper element, nor the usage of border-radius on the contained image (or any other child element) seem to be the cause of this as they can be interchanged and the pixelated edge will still appear.
This seems to indicate that this issue is solely caused by 2 DOM elements being in exactly the same place, when any sort of border-radius is applied to the wrapper element and the visible area of the child is limited to that of the parent's.
I've been having same issue and ended up using pseudo element instead of background, kinda like that:
figure::before {
content: '';
display: block;
background-color: red;
width: 400px;
height: 400px;
transform: scale(0.997);
border-radius: 50%;
}
This allowed me to create 'pseudo background' which I later shrinked a little bit with transform: scale(0.997); so it will be just the same size but a bit below visible edge. Of course in your case you would also need to position image absolutely so it is not pushed below by this ::before.
It appears that it is indeed a "feature" of how the browser handles border-radius to give a smooth edge to the rounded corners of a container. The image background is anti-aliased in the same way (but as it is transparent has no effect) as can be seen by setting the img background color.
When the border is anti-aliased it "bleeds" into the background to soften the edges and so you are seeing that around the image as a "jaggy" ring in much the same way you would see a corona around the moon during a full solar eclipse.
the issue is always there, whether the anti-aliased object is covered or not, if you were to draw a circle then anti-alias it, you would see the circle is marginally narrower than the anti-aliased version. Most anti-aliasing algorithms aggregate the surrounding pixels of the object rather than those contained within it.
To overcome it, you'd either need to make your image large enough to cover the space taken up by the anti-aliased edge or reduce the container such that the anti-aliased area is smaller than the image.
You could add a new tag with an opacity of 0 then have that fade in with the image fading out.
figure {
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
position: relative; /* For caption */
}
background {
background-color: red;
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
opacity: 0;
position: fixed;
z-index: 5;
transition: opacity 1s ease-out;
}
img {
border-radius: 50%; /* Forced on image for smooth transition */
width: 100%;
transition: opacity 1s ease-out;
position: relative;
z-index: 100;
}
figcaption {
position: absolute;
top: 100%;
left: 0;
width: 100%;
color: hotpink;
text-align: center;
transition: top 1s ease-out;
z-index: 10000;
}
figure:hover img {
opacity: 0;
}
figure:hover background {
opacity: 1;
}
figure:hover figcaption {
top: 50%;
}
<figure>
<background></background>
<img src="http://placehold.it/400x400" alt>
<figcaption>Demo</figcaption>
</figure>
Notice I added the background tag and removed background-color from figure
http://codepen.io/marczking/pen/KwMgaR
So after playing around (used background-image and pseudo-elements, changes nothing...) you notice that this light border is only visible if you apply round corners. So I am assuming here it has to do how the Browser renders the CSS, nothing wrong with the CSS-rules ^^)
<figure>
<figcaption>Demo</figcaption>
</figure>
figure {
background-color: red;
width: 400px;
height: 400px;
border-radius: 100px;
position: relative; /* For caption */
}
figure::before {
content: "";
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: url("http://placehold.it/400x400") no-repeat;
border-radius: 100px; /* Forced on image for smooth transition */
transition: opacity 1s ease-out;
}
figcaption {
position: absolute;
top: 100%;
left: 0;
width: 100%;
color: hotpink;
text-align: center;
transition: top 1s ease-out;
}
figure:hover::before {
opacity: 0;
}
figure:hover figcaption {
top: 50%;
}

CSS combination of :after and :hover:after on multiple HTML tags not behaving correctly

I am currently running into a problem when trying to implement a simple rollover using CSS :after and :hover pseudo-elements.
Have a look at the clock and facebook icons to the right: http://clean.philippchristoph.de/
Here's the CSS code:
.icon {
background: url('../img/clock_icon.png') top left no-repeat;
width: 25px;
height: 25px;
}
.icon:after {
.transition(opacity, .2s, ease);
content: " ";
position: absolute;
top: 4px; left: 5px; bottom: 0; right: 0;
background: url('../img/clock_icon.png') no-repeat;
background-position: -25px 0;
opacity: 0;
}
.icon:hover:after, .clock:hover div {
opacity: 1;
}
As you can see, the image is faded using a sprite and opacity. However, now I can't seem to hover both elements anymore. As you will see on the example page, you can hover over the facebook icon, but not over the clock. If you remove the facebook icon, you can hover over the clock again. Note that the two icons are entirely seperate elements.
I've tested this behavior on both FF and Chrome on Windows.
It'd be awesome if someone could shed some light onto this issue.. :)
Replace your CSS with this one (I mean the mentioned classes only, not your entire CSS :) ):
.icon {
background: url("../img/clock_icon.png") no-repeat scroll left top transparent;
height: 25px;
width: 25px;
position: relative
}
.icon:after {
-moz-transition: opacity 0.2s ease 0s;
background: url("../img/clock_icon.png") no-repeat scroll -25px 0pt transparent;
bottom: 0pt;
content: " ";
left: 0;
opacity: 0;
position: absolute;
right: 0pt;
top: 0;
}
.icon:hover:after, .clock:hover div {
opacity: 1;
}
.facebook, .facebook:after {
background-image: url("../img/facebook_icon.png");
}
.clock {
position: relative
}
.clock div {
-moz-transition: opacity 0.2s ease 0s;
color: #A0A0A0;
font-size: 12px;
left: 40px;
line-height: 11px;
opacity: 0;
position: absolute;
top: 5px;
width: 160px
}
You need to add position: relative to your icon class, so that the generated content is positioned relative to that, rather than the parent. I've tried to simplify what you have in a fiddle, though I wasn't 100% sure what you are after. Is that close? I also amended the positioning of the generated content.
It's worth noting that - annoyingly - you can't apply a transition to generated content (which is why any attempt to have the opacity transition on these elements will fail in your case). Hopefully this will change soon.

Resources