How to fix Firefox rotation glitch? - css

I'm afraid I'm facing a render glitch in the current Firefox (24.0), while Chrome (30) renders the same code as expected.
Here's the code: http://dabblet.com/gist/6982745
HTML:
<div class="triangle"></div>
CSS:
.triangle {
height: 50%;
width: 40%;
position: relative;
top: 50px;
left: 50px;
background-color: black;
overflow: hidden;
/*
* Here comes the malicious line:
*/
transform: rotate(-18deg);
}
.triangle:before {
content: "";
width: 200%;
height: 300%;
position: absolute;
background-color: white;
transform-origin: left top;
transform: rotate(-52deg);
}
.triangle:after {
content: "";
width: 200%;
height: 300%;
position: absolute;
top: 38%;
background-color: white;
transform-origin: left top;
transform: rotate(26deg);
}
Basically, there's a black square (.triangle) which is partially covered by rotated white squares (:before and :after) to create a triangle. The black square itself is rotated by 18 degrees - which causes Firefox to render some kind of gray border around .triangle - even if the both white squares should cover every pixel in this area.
Chrome, as a reference, omits such a border.
A little experimenting showed me that the glitch only occurs with rotations other than 0°, 90°, 180° ...
My questions are: Am I doing something wrong? (I know that there are simpler ways to create a triangle - it's just a simplified example) Is there a known workaround for this glitch? I already tried box-shadow and border - both without success.
Thanks in advance :)

Related

Perspective origin and vanishing points

I'm trying to understand how perspective-origin affects vanishing points. I understand that the red square should vanish into the absolute center, but it appears to vanish towards the center-right instead. The lines would converge towards the center-right. I know I'm misunderstanding this somehow, but I don't know what I'm missing. I've read through whatever documentation I could find on this.
.container {
background: gray;
width: 200px;
height: 200px;
perspective: 50px;
perspective-origin: center center;
}
.contained {
background: red;
width: 100%;
height: 100%;
transform: rotateY(45deg);
transform-origin: center left;
opacity: .5;
}
<div class="container"><div class="contained"></div></div>

Why does Chrome cause this border / bleed around this image when using translate?

See this fiddle:
https://jsfiddle.net/uy6yhv4d/1/
I have an img with background-color: red set.
When rendered on the page normally, without using transform, it appears as expected, with no red border.
However, when I trasform: translate it for positioning, the red background now "bleeds" the edges, causing a red border to appear.
Why does this happen?
The red border is coming from the background-color: red;. I found that removing the point values from the dimensions removed the appearance of a red border:
img {
height: 256px;
width: 200px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: red;
}

Angled Border using skew with Box Shadow - FF issue

Trying to add an angled border to my header and then also adding a box shadow around the angled border.
Seems to work fine but on Firefox there is some white background showing around the box shadow.
Code is as follow
header {
background: #41ade5;
color: #fff;
position: relative;
z-index: 1;
padding: 45px;
}
header:after {
background: inherit;
bottom: 0;
content: '';
display: block;
height: 50%;
left: 0;
position: absolute;
right: 0;
transform: skewY(-1.5deg);
transform-origin: 100%;
z-index: -1;
box-shadow: 0px 4px 4px rgba(0,0,0,0.5)
}
body {
margin:0;
}
http://codepen.io/velnias2015/pen/KaBzrq
Looks fine on all other browsers, is there a fix for firefox ?
Add translateZ(1px) to fix the antialiasing issue with the transform.
transform: translateZ(1px) skewY(-1.5deg);
Render issues with transforms are common and modifying 3d transform properties are often the best way to fix them because it causes the browser to render using different methods. Other common fixes in this same vein but don't seem to apply here are: backface-visibility: hidden and perspective: 1px.

CSS negative triangle with inverted rounded corner

Hello is it possible create a triangle with inverted rounded corner in the center of a rectangle, like in many landing page. Something like the below image:
I found something similar here but without inverted rounded corner
CSS Inverted Triangle image overlay
Yes, it is possible to achieve this effect by using two pseudo-elements. We need to position one of the pseudo-elements with respect to the left of the container while other is positioned with respect to right of the container. Then by adding a transform: skew() on them in opposite directions and assigning a border-radius to the required sides we can get the required output.
div {
position: relative;
height: 50px;
width: 100%;
padding-top: 50px;
background: blue;
background-clip: content-box;
/* make sure blue background doesn't appear behind triangle */
overflow: hidden;
color: white;
}
div:before,
div:after {
position: absolute;
content: '';
top: 0;
width: calc(50% + 10px);
/* don't change */
height: 50px;
/* must be equal to padding-top */
background: blue;
}
div:before {
left: 0;
transform: skew(45deg);
transform-origin: right bottom;
border-top-right-radius: 12px;
}
div:after {
right: 0;
transform: skew(-45deg);
transform-origin: left bottom;
border-top-left-radius: 12px;
}
<div class='shape'>This is a shape.</div>

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%;
}

Resources