Blurry text in chrome on < button> element related to css transform? - css

I am using a menu that is animated using a transformation of an < svg> element with buttons on top of it. Strangely the text on the buttons is extremely blurred in chrome, while it is nice and crisp in all other browsers I have tested so far.
The blurry text is not related to the < svg> element. (which was my first guess) If I remove it the text is still blurred. It seems to be related to the < button> element. Just displaying the text without it being in the < button> gives nice and crisp text in chrome.
This is the css currently assigned to the button element:
.grid figure button {
top: 50%;
left: 50%;
border: medium none;
background: #316BA8 none repeat scroll 0% 0%;
color: #FFF;
opacity: 0;
transform: translateY(-50%) translateX(-50%) scale(0.25);
this is the transform that takes place on hover: (when the buttons with the blurry text come up)
.grid div:hover figure button {
opacity: 0.9;
-webkit-transform: translateY(-50%) translateX(-50%) scale(1);
transform: translateY(-50%) translateX(-50%) scale(1);
}
I have found other posts relating blurry text in browsers (not always chrome) to css transformation but I haven't been able to find any answer that could have been applied to my problem. Any ideas?
Thanks!

It's the scaling (maybe even because it's combined with opacity 0.9) - try finding the sweet spot if you can or try checking if it works better with/without the hardware acceleration.
But there's not much more you can do about it because it's entirely done by a browser.

Related

Unknown CSS code in theme causing image to blur

The wordpress theme I have, NeoBeat is causing my logo at top to be blurry.
My site is earthcry.net
The CSS for the image above is
opacity: 1;
position: absolute;
top: 50%;
left: 0;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
It's actually being caused by this css here which is reducing the size and causing the blur:
#qodef-page-header .qodef-header-logo-link img {
display: block;
margin: auto 0;
width: auto; // Comment this out or delete
max-height: 100%; // Comment this out or delete
-webkit-transition: opacity .3s ease;
-o-transition: opacity .3s ease;
transition: opacity .3s ease;
}
If you get rid of those, it shows at it's intended size.
This is actually a relatively common issue with using the (relatively old hat) method of vertical centering with absolute positions. A quick search here, The Goog, The duck site, etc, will show many results for "blurry <element> with transforms`.
The easiest and most pragmatic way to deal with this is to not use the "absolute/50%/transform -50%" method to center elements, and upgrade to using flex, align-items: center and justify-content: center. There's all sorts of hacky ways to fix the blur, but you'll need to cycle through them and find which works for you (basically, it's being perfectly centered in a 69px tall element so it's got half a pixel on each side of center to deal with that it can't place, so it aliases it.)
However, with all of that said, it looks like you don't actually need a centering mechanism at all.
All you need to do is remove the actual position overrides and transforms. Here's your logo as it stands (it seems to be correct on mobile).
If you instead just used:
opacity: 1;
position: absolute;
It would look just fine:
Just remove the top, left and vendor-prefixed transform: translateY and you should be good to go.
(The previews in the answer may be blurry, click on them to open them up though, I promise the latter one is crisp, lol)

Regarding HTML 5 topic name SVG

In the following code why do we use the webkit and ms keywords?
#svgelem {
position: relative;
left: 50%;
-webkit-transform: translateX(-20%);
-ms-transform: translateX(-20%);
transform: translateX(-20%);
}
EDIT: The ms- and webkit- keywords are used so each of the different CSS processors versions (microsoft (ms) and webkit) know how to handle that line. This is because of experimental features, like transform, being added by each of the CSS processors at different times.
The typical use of a block of CSS like this is used to move an element to the centre of it's parent object on the horizontal axis.
The idea is to move the element to so the left edge is in the middle of the parent:
#svgelemn {
position: relative;
left: 50%;
}
Now that the element is just to the right of the middle (remember that it's the left edge that is in the middle), you need to move the element to the left by 50% of it's own width (not it's parents width). Because we're moving the element to the left, we also need to invert the percentage so it's negative (-50%). So now you add the transform section:
#svgelemn {
position: relative;
left: 50%;
-webkit-transform: translateX(-50%); /* Webkit specific transform */
-ms-transform: translateX(-50%); /* Microsoft specific transform */
transform: translateX(-50%); /* Generic transform (all evergreen browsers) */
}
The code that you have only makes a final adjustment of only 20%, so that's not quite the middle.
You can see an example here. You can see how the top element is in the middle, while the original code makes it slightly off centre.

Gap between border-image after using transform: rotate

I am trying to create a box with a jagged edge, that can actually be used as a HTML element should be, and can resize etc.
Finally got my head around border-image, got it looking nice, and then when I rotate it, it gets a gap between the border-image and the main fill:
I googled it, and found an answer on SO telling someone to set
-webkit-backface-visibility: hidden;
This cleared it up, but obviously only in webkit browsers.
I tried using -moz-backface-visibility as well, but it didn't clear the issue up in Firefox.
Any suggestions?
jsFiddle
e: I actually thought I may be able to fix it by setting a background color, and then setting the background-clip to padding-box, but honestly it just left me in the same position.
One trick that fixes the problem both in Webkit and FF is setting perspective (instead of backface visibility)
.box.one {
-webkit-transform: perspective(999px) rotate(1deg);
-moz-transform: rotate(1deg);
-ms-transform: rotate(1deg);
-o-transform: rotate(1deg);
transform: perspective(999px) rotate(1deg);
}
fiddle
Adding an after pseudo class with negative margin seems to fix the Firefox issue.
.rough:after {
content: "";
display: block;
margin: -1px;
height: 302px;
background: black;
}
Fiddle demo: http://jsfiddle.net/Wkk7W/3/
Note that the display:block seems to be an essential part of my hack/fix.
Update: Depending on your plans for content inside the div, that exact example might not suit. However, I think the concept could be tweaked depending on your requirements - e.g. using a 3px wide black border instead of a background fill, and using position:absolute to allow other text to be layered on top of the box.
Gonna answer myself, because this solution actually covers my needs of it being "as a html element should be, and can resize etc", even though I developed this solution from Grants answer.
http://jsfiddle.net/Wkk7W/6/
Set the element to position:absolute, then give it a pseudo element with:
content: "";
display: block;
position: absolute;
top: 0;
width: 102%;
margin: -1px 0 0 -1%;
height: 102%;
background: black;
z-index: -1;
This way it keeps the elements width and height, z-index: -1 to put it behind the text. It might not require the display:block, i didn't check.
There are still a few tiny gaps but they are basically impossible to cover and I am happy with it the way it is.

When using CSS Scale in Firefox, element keeps original position

When using scale in Firefox, the scaled element dóes get scaled properly. The problem is, that it's positioned as if it isn't scaled.
This works fine in Chrome, and probably also in IE, Safari and Opera. These browsers all support the CSS zoom property, where Firefox doesn't. For Firefox I'm using -moz-transform: scale(0.3);.
This is my CSS:
#overview .page-content {
zoom: 0.3;
-moz-transform: scale(0.3);
}
This is what it should look like (as in Chrome):
This is what it shouldn't look like (as in Firefox):
Does anybody know how to fix this? Or maybe a workaround?
As thirtydot mentioned:
position: absolute;
-moz-transform-origin: 0 0;
This will do the trick.
I added -transform-origin: 0 0; and it still did not work.
Somehow in Chrome it collapsed to -webkit-transform-origin: 0;
So I changed it to -transform-origin: top left; and it works fine now.
Full code:
-moz-transform: scale(50%);
-moz-transform-origin: top left;
-o-transform: scale(50%);
-o-transform-origin: top left;
-webkit-transform: scale(50%);
-webkit-transform-origin: top left;
If absolute positioning is not an option - and aware of according browser support - display: table-cell with a min-width definition, should needs be, might do the trick as well.
E.g. this helped me to get a row with customer logos scaling well across different screen resolutions.

Positing rotated text along div

First of all, an image of what I am trying to acheive:
Sample here:
http://i.imgur.com/3BpFF.png
The white box with the word 'div' in it is obviously the div I have. For my purposes, it's a div centered in a page using width:500px; margin: 0 auto;. What I want is to be able to align some rotated text (using -moz-transform: rotate(90deg) or alternatively prefixed rotates) along the top of the div, like the word 'Holy' above (sample text). I would also like to set the baseline on that div, though it isn't that important.
By the way, I used some absolute positioning in Firebug to get the text aligned there - it was hacked there using per pixel positioning. It's not very flexible (if at all) because once I increase the font size or change the position of the div, it's broken.
Also: I am open to using SASS and other such things (I don't have any experience with it yet, but I do I think it allows use of variables which may help).
When you can use CSS transform it means you can use pseudo elements in your CSS code. Then I will add that "Holly" part via :after pseudo element.
div:after{
content:"Holy";
line-height:20px;
position:absolute;
background:yellow;
padding:0 10px;
left:100%; top:0;
-webkit-transform:rotate(90deg) translateY(-100%);
-webkit-transform-origin:0 0;
}
As you can see I've use translateY to move this part out of the div, because we rotated the thing before then translateY will work as translateX.
transform-origin is set to 0 0.
This code is independent from you div size.
Look at it live here:
http://jsbin.com/akaziy/2/
You can place something like this in your .css file (the margin-top & margin-bottom are just examples)
div {
width:500px;
margin: 0px auto;
}
.holly {
margin-top:20px;
margin-left:520px
/* Safari */
-webkit-transform: rotate(90deg);
/* Firefox */
-moz-transform: rotate(90deg);
/* IE */
-ms-transform: rotate(90deg);
/* Opera */
-o-transform: rotate(90deg);
/* Internet Explorer 9*/
-ms-transform: rotate(90deg);
/*undefined prefix*/
transform: rotate(90deg);
}

Resources