Using calc() to transition width and height in IE - css

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

Related

Unexpected/Incorrect scale size for transform: scale" when zoom in/out chrome browser

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);

How to change width of a Sidenav in Angular Material Design?

No matter what screen size I use, the Sidenav is always the same size. I tried adding attributes such as
- flex
- flex="85" (to get 85% of its container)
Can't seem to find a good approach.
In angular material, md-sidenav has these attributes:
width: 304px;
min-width: 304px;
That's why the width will be fixed at 304 px no matter what device you use.
So if you want to change your sidenav width you'll have to change the css a bit.
If you're fine with supporting only modern browsers, you can change it to a vw measure (1/100th of the viewport width) and add it to a separate css file. The code will look something like this:
md-sidenav,
md-sidenav.md-locked-open,
md-sidenav.md-closed.md-locked-open-add-active {
min-width: 200px !important;
width: 85vw !important;
max-width: 400px !important;
}
Here's a plunker: http://plnkr.co/edit/cXfJzxsAFXA3Lh4TiWUk?p=preview
The answer submitted by user3587412 allowed me to change the width but I was having the same problem as Craig Shearer with it killing the animation. So I tried a few different things and came up with this.
md-sidenav.md-locked-open {
width: 250px;
min-width: 250px;
max-width: 250px;
}
I'm not sure if that is the proper way but it seemed to work for me.
Thanks to user3587412 I could find easily the required styles.
To get the md-sidenav to adjust to a flex parent just override
md-sidenav,
md-sidenav.md-locked-open,
md-sidenav.md-closed.md-locked-open-add-active {
min-width: 0px !important;
width: auto !important;
max-width: none !important;
}
After trying different CSS in this thread I end up with :
md-sidenav,
md-sidenav.md-locked-open-add-active,
md-sidenav.md-closed.md-locked-open-add-active,
md-sidenav.md-locked-open {
width: 200px;
min-width: 200px;
max-width: 200px;
}
I'm currently on angular-material 1.0.8 and tested with Chrome 50 only.
With this CSS what works for me :
Animation close and open OK
When locked OK
When not locked OK
In case anyone comes here using the latest mat-sidenav, you can explicitly set the width on the the element.
mat-sidenav {
width: 200px;
}
The docs caution against using percentage based sizes.
https://material.angular.io/components/sidenav/overview#setting-the-sidenavs-size
Here's a somewhat "jank" solution, but it doesn't mess with the animations at all. The sidenav automatically resizes itself in order of the items inside it to fit perfectly. As such, you can just add a span with the width of your choice to the mat-drawer to set a minimum size. Note that this only works to set a minimum width, and not a maximum width.
<span style="height: 0px; width: 200px; display: inline-block;"></span>
I came across this issue, as well -- even though the 304px width is plenty, I had a card in the content area to the right that was squeezing the sidenav. So, using the flex grid I was able to add <md-sidenav flex="15" class="md-sidenav-left ... to get the width I wanted without overriding CSS. It sounds like this didn't work for you, so maybe it has to do with the layout options in your design...

Google Chrome Border Radius issue

Hi there I am working on this site - http://smudgedigital.com/animation-projects/ and have an issue with the gallery on the projects page. The images should all be a circle and when rolled over the the image should remain a circle and have a hover black state.
However despite the site working fine I have recently noticed that the circles are no longer circles in google chrome. The are in fact square on all states.
I have looked through this site to find any answers but none of them seem to work. I have tried using the border radius code for all browsers;
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
border-radius: 100%;
but it does not seem to pick it up, even when I use the !important tag. I have also tried using pixels instead of percent. When I use the inspect element tool I can add this;
.view img {
display: block;
position: relative;
border-radius: 100%;
}
and it works on the normal state, but when I put it into my site css it does not appear.
I have seen some people say that google just doesnt understand the overflow: hidden property and it has nothing to do with the border radius, however overflow: hidden does appear.
Any help would be greatly appreciated. I have built the site on wordpress.
Thanks,
This looks to be a known bug in Chrome I'm afraid. It's related to transition mainly, and how the order of parent/child becomes when the DOM is being painted during a transition:
https://code.google.com/p/chromium/issues/detail?id=157218
As an alternative you could maybe make the entire circle including border and shadow increase in size. However I don't think that is the effect you want.
Please also see this thread on Stack Overflow: Bug with transform: scale and overflow: hidden in Chrome
Added
.view-first img {
transition: all 0.2s linear;
border-radius: 100%; /* added new */
}
removed
.view{
overflow:hidden; /* removed */
}

Border-radius: 50% not producing perfect circles in Chrome

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.

Problem with percentage based widths in Opera

I'm trying to make a fluid grid layout and I've run into a problem with inconsistent width rendering in Opera. In Opera the width of elements are consistently smaller than the other browsers. I'm trying the fluid 960 grid system but if it wont be consistent then I may change to fixed sizes.
Does anyone know how I can get Opera to render the width the same as the other browsers?
Here is the CSS and HTML I'm using for this demo
.show_grid {
background: url(../img/grid.gif) no-repeat center top;
}
html, body{
margin: 0;
padding: 0;
}
.container {
width: 92%;
margin-left: auto;
margin-right: auto;
max-width: 936px;
padding-top: 15%;
}
.box {
width: 15.633%;
background: #006;
color: #999;
margin: 5% .55%
}
<div class="container show_grid">
<div class="box">2 column - browser name</div>
</div>
Opera rounds percent widths but it doesn't round percentage values for paddings and margins.
So, the easy way is to set the width: 15%, and add padding-right:.633%. But doing so, only the block would be bigger visually.
If you want to have it's width fair so all childs would have the same width, you'll need to add another wrapper and add the appropriate negative margin to it. It is calculated by this formula: 100/width*padding, in your case: 100/15*0.633. It would compensate the padding and everything would be cool.
Here is a fiddle with all the variants: http://jsfiddle.net/kizu/8q23d/
— fixed width in pixels, block with width:15.633%, first visual fix and the proper fix at the end.
Dealing with different box models could be very tricky and time consuming.
I definitely suggest you to avoid dirty CSS hacks that will not validate your css files.
You could try to drop the use of percentage values and go for an "elastic" layout.
In this case you specify the min-width and max-width for your block elements.
An article about elastic layout is here and something more here
In alternative you could detect the browser via javascript or via library and use conditional CSS files.
This is my favorite approach when dealing with IE.
conditional css is a library that will help you with that, but there are many more options in the web.
Good luck

Resources