Usually border-radius: 50% works fine for most applications, and Chrome produces what looks like a circle. But in this instance, I am trying to continually rotate a circle quickly, and this is where this problems shows itself.
Is this a bug with Chrome's border-radius? Or is this something with the transform?
Can anyone suggest a work around?
Edit: removed outdated example link
It's caused by the roundings in the way the "radius" is calculated. Since the size is an even number the border is "in-between" two pixels... long history, at the end:
Workarround: Set your divs circles size an "odd" number of pixels.
$ring-medium-outer: 437px;
$ring-medium-inner: 381px;
We have a solution an effective solution as of Dec 2022: Compatible with all major browsers...
If the border-radius value is half of the width value for that specific element; in CSS, we get a full circle for that element, provided that a height property with an equal value of the width or an aspect-ratio property is specified for that element. Example with an img element below…
img {
width: 150px;
border-radius: 75px;
aspect-ratio: 1 / 1;
}
OR
img {
width: 150px;
height: 150px;
border-radius: 75px;
}
Extra Note: To scale the width and height dynamically for dynamic CSS’ units, aspect-ratio property to the rescue.
Related
The incorrect scaled size happens in Webkit browsers, i.e. Chrome, Safari. Chrome version I am using is 68.
Demo: Codepen Link
Code as requested by #Kaiido
HTML:
<div class="test1"></div>
<div class="test2"></div>
CSS:
.test1 {
z-index: 100;
position: fixed;
top: 10px;
left: 10px;
width: 1px;
height: 1px;
background: blue;
transform-origin: top left;
transform: scale(100, 100);
}
.test2 {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: red;
}
In the link above, if you zoom in/out of chrome, you would see the scale size does not necessary match the fixed size of the .test2 div. I would expect the final size of the scale(100, 100) to be exactly the same as the one with width:100px; height: 100px upon scaling but obviously this is not the case.
I have also tested this in both retina mac and pc. It is the same behavior in Chrome. However same code is tested in Firefox and is working correctly.
Is this some sort of bug or am I missing something? Thanks.
It is a bug... caused by the fact these browsers round coordinates to avoid antialiasing.
So when you set your zoom level to 120%, the small square should actually be rendered as a 1.2px*1.2px square prior transform.
But webkit browsers will round this value to 1px, even before they apply the transformation (I think FF also does but probably after transform).
So you won't see a change until you get to zoom 150%, where now it will get rounded to 2px and your blue square will get bigger than the same 100px*100px.
Only at 200% will they match again.
Not much to do to circumvent this, apart letting them know, and avoiding playing with such small elements ;-) (using a 10px*10px square and dividing the transform zoom level by 10 would prevent this bug).
Have caught similar case on mobile Chrome. Scaling 1px value to some width by CSS transform after ~100px result become totally wrong and become worser as continue. In my case this was a js-based range control, where I scale its 'progress' visual part from 1px (base) to current user touchX position by transform: scaleX(touchX);
My vision of problem is based on understanding of CSS units evaluations (https://webplatform.github.io/docs/tutorials/understanding-css-units/): there is sort of eager integer equation for antialiasing on screens with fractional window.devicePixelRatio. Android often has a 2.3, 2.6 DPRs, and it may changes when user changes display's zoom system settings.
My solution involves javascript, so may be inappropriate for you, still may be useful:
fixedWidth = (devicePixelRatio * originalWidth) / Math.round(devicePixelRatio);
I've come across an issue today where trying to use CSS transitions to change an object's dimensions with calc() aren't working in IE. Or, rather, they're working in the sense that the calculated values are being applied but the transition rules are being ignored.
See an example here: http://jsfiddle.net/32Qr7/
.block {
width: 350px; height: 100px;
background-color: red;
margin: 10px; padding-left: 10px;
transition: all 1s ease-in-out;
}
.block:hover {
width: calc(100% - 50px);
height: calc(150px + 10%);
}
In this example, a div exists which changes its' width, height, and background-color over the course of one second on hover. In IE the background color still animates smoothly, but the width and height change is instantaneous.
This is pretty big issue for me as I have a responsive web app with drawers that slide out from the side, and the rest of the layout has to adjust to compensate. Since I'm dealing with a multitude of screen sizes I can't use hard-coded values.
(And yes, I looked at IE 10 + 11: CSS transitions with calc() do not work hoping for a solution there, but that question doesn't involve dimension changes, and as such the accepted solution there doesn't work for me.)
Does anyone know of a workaround for this issue, or have any other alternate strategies to suggest? I'm hoping to be able to do it in CSS and avoid having to fall back to using jQuery animation techniques or somesuch.
Seems like I have found a workaround after playing a bit (at least it works for IE10 and IE11). I have used the max-width property instead for calc() method. CSS for hover:
.notworks:hover {
width: 100%;
max-width: calc(100% - 50px);
height: 175px;
}
Example
I have a div set with a background image:
<div>Play Video</div>
with the following CSS:
div {
background-image: url('icon.png');
background-image: url('icon.svg'), none;
background-size: 40px 40px;
background-repeat: no-repeat;
background-position: 90% 50%;
padding: 20px;
width: 150px;
}
The background size is respected in Firefox, Safari and Chrome. In IE8, the SVG is replaced by the PNG file. However, in IE9 and IE10, the SVG file is drastically sized down. The problem seems to be linked to the width and height of the div. If I add a height of 150px, the SVG is rendered properly. If I make it smaller (i.e. 100px) the graphic starts to shrink.
Has anyone found a way to fix this issue in Explorer? Is there a way to tell IE to use the background-size value independently of the width and height of the div?
Be sure that your SVG has a width and height specified. If you're generating it from Illustrator, ensure that the "Responsive" box is unchecked as this option removes width and height.
Adding a width and height to the SVG as mbxtr said nearly worked for me. I needed to add preserveAspectRatio="none slice" as well to get it working responsively in IE.
For me these 3 fixes helped:
If possible set the background-position to "center"
For background-size set both values, "100% auto" won't do the trick, so use "100% 100%"
If that still doesn't help alter the last to values "viewBox" attribute of the SVG itself and make it one pixel wider and higher than the width and the height of the SVG. This shrinks the SVG a little bit, but stops IE from cutting it off - and the smaller size won't be noticed at all.
I had this issue and I found that either removing the height and width inside the code for the svg BUT keeping the viewBox can solve the issue.
I recommend using a compiler site like : https://jakearchibald.github.io/svgomg/
and setting the option to "prefer viewBox over height and width"
ALSO if none of this works, in Illustrator try applying a square background around the svg image but leaving enough padding around the edges.
And import the svg's in your Stylesheet using --> data uri: ...
example:
background-image: data-uri('image/svg+xml;charset=UTF-8',' where/your/svg/is/located');
Well, it doesn't look like there is a solution. Surprise surprise. It's IE after all. I ended up using the following code:
div {
padding: 20px;
width: 150px;
position: relative;
}
div:after {
position: absolute;
content: "";
width: 40px;
height: 40px;
top: 50%;
right: 30px;
margin-top: -20px;
background-image: url('icon.png');
background-image: url('icon.svg'), none;
}
I liked the cleaner version better, but this hack works in all modern browsers, including IE8, 9, and 10 (probably 11 but I didn't test).
We had a similar issue with SVG background images that weren't the full site of a containing element (such as the magnifying glass at the left side of a search input).
We'd created out SVGs in Illustrator CC but running them through Peter Collingridge's SVG optimiser to take out all the unnecessary cruft did the trick. http://petercollingridge.appspot.com/svg-optimiser
I tried #mbxtr's solution
Be sure that your SVG has a width and height specified. If you're generating it from Illustrator, ensure that the "Responsive" box is unchecked as this option removes width and height.
That still didn't work for me on windows Chrome and IE.
I was exporting a font icon, so if you have a font, make sure you export it as:
"font: convert to outlines"
and "responsive" is false
I also unchecked "minify" just in case...
1. javascript
drips.style.top = -dripsTop + "px";
var browser = window.navigator.userAgent;
if (browser.indexOf("Trident") > 0) {
$(".flow_space").css({"background":"url(../img/space2-ie.svg) no-repeat", "background-size":"100%"});
}
svg (original height=1050)
add directly to himself svg file
preserveAspectRatio="none" height="2100"
Svg background image size will render same on IE and Chrome using these properties
background: #ffffff url("images/calendar.svg") no-repeat;
border: 1px solid #dddddd;
float: left;
margin: 0;
overflow: hidden;
background-size:15px 15px;
I changed all my SVGs to not responsive in Illustrator to no avail.
And because I am looking for code examples I missed that the correct answer, when saying "ensure your SVG has a width and height specified", they meant this kind of thing:
.my-class {
background-size: 200px 100px;
}
And if the size is a bit off in IE vs Chrome for example I used a media query to target IE:
#media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
.my-class {
background-size: 200px 110px;
}
}
I have a series of containers, all set to height 100% starting from 'body'.
I set 'article':
article {
width: 100%;
height: 50%;
margin: 0;
margin-top: 25%;
padding: 0;
}
The height works fine taking half of its parent's (or screen, doesn't matter) height, but the margin-top is definitely not 25%, more like three times it.
Live link: http://no-plans.com/temp/wp-tobias/wordpress/?p=51
Disclaimer: still dirty stylesheet, there might be inherited conflicts but I can't find any. I also tried to resize and put the margin to other parent divs, same issue.
As stated in the comment, margin percentages are relative to container's width: http://w3.org/TR/CSS21/box.html#margin-properties.
You can solve by absolute positioning and top (here the percentages are relative to container's height).
I am trying to create a square(or div) in the browser according the size of the screen, so I am using percentage, i want the square to be 40% of the height of the screen, and get the amount of this percentage in pixels and use it for the width in order to get a square. And also use these values to center it. I know that with javascript should be easy, but i am new to less and I am wondering how this can be done. I tried the following and doesnt work:
#base:calc(40% * 1px);
#mytransform {
background-color:#ccc;
height:#base;
width:#base;
position:absolute;
top:50%;
left:50%;
margin-top:-(#base/2);
margin-left:-(#base/2);
}
how can i transform percentage to pixels?
You Cannot Do What You Desire With Precompiled LESS
LESS is a CSS preprocessor. That means it processes the code to form it into CSS before the browser ever sees it; and as far as LESS is concerned, the browser does not exist. What that means is, 40% of the height of the browser window is totally unknown to LESS. All that it knows is 40%, having no idea what that will actually translate into for pixels at a later time.
You will either want to stick to javascript, or use extra html mark-up to get the squaring effect.
Client-Side Compiling (NOT Recommend for Production)
I need to stress the fact that client-side compiling is recommended only for development. If someone has javascript turned off, then they will get NO styling. And those that have it turned on are going to experience a slowdown in page loading.
Now, the reason you get an invalid type error is because the returned value needs to be made into a number that LESS understands (I think it is treating the returned value as a string). This can be easily done like so (see the changes to the #base assignment):
#base: (0.4 * unit(`window.innerHeight`, px));
#mytransform {
background-color:#ccc;
height:#base;
width:#base;
position:absolute;
top:50%;
left:50%;
margin-top:-(#base/2);
margin-left:-(#base/2);
}
My CSS Output On One Run At less2css.org
#mytransform {
background-color: #ccc;
height: 243.60000000000002px;
width: 243.60000000000002px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -121.80000000000001px;
margin-left: -121.80000000000001px;
}
I had a similar task: "Center a square div according screen-width/height".
Try using CSS's vmin (compare CSS Specification) as in my jsfiddle to get e.g. a squared div centered with 50% of the minimum of horizontal/vertical viewport in percent.
CSS to scale and center div as described:
.centeredDiv {
width: 50vmin;
height: 50vmin;
position: absolute;
top: 50%;
left: 50%;
margin-top: -25vmin;
margin-left: -25vmin;
background: #FF0000;
}
View port-tag you may need in your mobile website
<meta content="width=device-width,initial-scale=1" name="viewport">
(I had troubles on iOS when adding "maximum-scale" or "user-scalable" in content-attribute)
Please find jsFiddle for reference here:
http://jsfiddle.net/YCawM/
CSS pure solution, this code will create a div of 40% width and height of the viewport and it will position it in the center of viewport.
Use position:fixed; to keep the button positioned relative to the viewport.
Use left and top properties to position your div.
With calc(), you can perform calculations to determine CSS property values.
Use vw and vh units to get the viewport dimensions.
With with 50vw you say to browser to position at 50% of the viewport width, and you need subtract 20% (= 50% of you div size which it turn to be 40% of the viewport).
#target{
position:fixed;
width: 40vw;
height: 40vh;
left: calc(50vw - 20%);
top: calc(50vh - 20%);
background-color:red;
}
<div id="target"></div>