I would like to animate the width of a container with multiple divs using CSS3 transitions. Each child has a background and a property background-size: cover.
I prefer to use CSS3 scale rather than width for better performances. But with scale the background doesn't keep its aspect ratio.
Here is a fiddle showing the problem.
Is it possible to keep aspect ratio?
I don't think it is possible using scale.
You see, the thing is when you use width to scale the div it forces the browser to do some math for the element and an entire box model, it doeas the layout of the CSS and repaints and rerenders it entirely.
When you use scale it moves your element to a separate layer and it doesn't recalculate anything, it's just the GPU that processes your element in a very "graphical" way, so scaling 0,5 is just shrinking it visually and thats it. This is the reasony why, as you said, CSS transform is better in terms of performance - because it doesn't recalculate things, but there are some drawbacks of using those transform as you can see. Since it deosn't do the math, it cannot do background-size: cover because there is just not enaugh information to know how to paint it.
Or, let me put it this way: if you do width: 50% browser calculates the width of the element and knows it - thanks to that information it can position your background the way you want (and you want it to cover so its doing the math, taking the width, height, you background image size etc.).
If you do scale it doesn't know the width of the element in terms of CSS layout, it doesn't even care. It just knows how wide it was initialy (visually), renders the layer and than just shrinks it down without any further processing whatsoever. And since its GPU doing that, it's really really fast.
Related
I'm trying to set up an effect like telegrams chat scrolling, where there is a global gradient positioned relative to the screen (fixed), and any element that is at the top of the screen would be a different color than the bottom of the screen.
Scrolling elements in this container would effectively change the color of each item, but the color at any position on the screen is static.
I'm wondering what is the most efficient & flexible way I can achieve this? Two options I'm evaluating personally:
Using background-attachment: fixed and having giving all items the same background-image.
Using clip-path in some manner (although I have never used this property before).
However, I'm not entirely clear on how either of these would work, or if there is a better solution.
I tried to find an animated example but could only find a static example:
I'm currently trying to make a responsive navbar (and it works, is responsive), but at some window size, it becomes too big. So I tried to use #media (max-width) to block its growth at some point. Unfortunately, when I use px to describe new fixed size, the navbar is now affected by scaling of the page (ctrl+mouse wheel), and I'm trying to avoid this behavior.
Is there a workaround to my problem?
Little hard to understand your question, but any good navbar should scale width wise for a page. I kinda sounds like you set the height style to a percentage rather than pixel amount.
<div style='height:80px;width:100%;'>Content</div>
This makes a horizontally scaling bar, with a constant heigjht
This is kind of a specific question.
<div id="d_btn">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
</div>
Here's a jsfiddle: https://jsfiddle.net/fcjwjutb/
you'll notice it creates an image button which is really just a div with a background image, and that thanks to a base64 data of a single transparent pixel the aspect ratio is always 1:1 (a different pixel w/h would give different aspect ratio). it changes the image when you hover.
the problem is: if I resize the window vertically, the aspect ratio breaks.
however, automagically, if you refresh the page - the aspect ratio returns to normal.
what I want is the aspect ratio to stay correct while you resize the window, without having to refresh. what would I need to change in this specific example to accomplish this? looking for a CSS answer, not JS.
the "trick" to maintain aspect ratio here is the fact that if you set only height or only width, the other parameter should automatically maintain scale if there's an image involved, that's what the 1pixel is for.
I don't get why this breaks upon resize though, when initially upon page load it works correctly.
The issue seems to revolve around the fact that when you resize, the div's background image stretches instead of... well... not stretching. but the div itself also gets resized, while the img child inside of it doesn't, and maintains its aspect ratio as intended.
after seeing some incorrect answers let me make something clear:
the div and the image size have to match. hover event should only get triggered when you hover over the image itself, otherwise this doesn't feel like a "button". basically you're not allowed to have a div larger than the image, or else you create blank area that triggers a hover event.
the answer I'm looking for is one that is able to make the div itself resize in a way that keeps the aspect ratio while you resize the window, while having the background image always cover the entire div.
You can use background-size property to ensure background images maintain their aspect ratio within a given container.
It is also bad practice to use IDs for elements like this one.
I have solved the problem for you...
https://jsfiddle.net/x18h41yr/
You can also use flex-box to now centre page elements vertically & horizontally. Read more about flexbox here
Is it possible via CSS to force the background-image which is repeating that it should be completely visible (not cut at the end of the container)? The container-height is flexible!
It should look like on the right side but I get a result like on the left side if the content
grows.
There are two possible ways:
avoid the background-image to overflow (I can't use background-size: contain because it's repeating)
force the container to grow gradually
Is this possible?
this is not the best solution but maybe it will help: if you can ignore IE8 and below, you can use the background-size property, it will allow you adjust the size of the images with percents so they will feet completely to what you need (and will stay in the same position at resize), then you can use the background-position property and move the images little bit for a better result. then, when you will try to resize it you will see that it stays in the same ratio on the screen but the images are getting bigger because of the percents, so make sure to upload bigger images from scratch so when the images will get bigger they will not resize above the real image size.
example: http://jsfiddle.net/fq5dkL51/2/
Is there a purely CSS-based way to size a block-level element such that it fills its parent as much as possible, but remains square?
An interesting use case
I have written a very simple analogue clock using mostly CSS, and a pinch of JavaScript.
http://jsbin.com/iqicuk
It has been written scalably:
http://jsbin.com/emiyer
I would like to scale it to fill the page, but stay in proportion, obviously.
If I set the width and height of #clock to 100%, of course, it will be pulled out of proportion:
http://jsbin.com/esubol
You can't do that with pure CSS, but you can do it with Javascript - and I assume you have Javascript running anyway to resize the parent element.
A solution in progress
thirtydot came up with a very clever technique that takes advantage of the fact that images with only one defined dimension scale proportionately, and he harnesses this to size the element. We now have a clock that can scale properly, but only if the viewport width is greater than the height, not the other way around:
http://jsbin.com/isixug
Likewise, if we change img and #clock to have a defined width, instead of a defined height, then we have a clock that can scale properly, but only if the viewport height is greater than the width:
http://jsbin.com/awucun
The solution
We can combine the two 'tricks' above, that each only work for one orientation, by using a media query for orientation, and specifying the right 'trick' depending on the viewport orientation. We now have a completely scalable clock, no matter what the viewport orientation or size:
http://jsbin.com/okodib
Any in flow block level element will already inherit the width from its parent. For the height however you will need to find an alternative.
I doubt this is something you will want to do but if you set your parent to position: relative; and then the child you want to make fill up that parent position: absolute;. Then specify where it needs to stick to relative to its parent with top:0;left:0;bottom:0;right:0;.
However this solution has compatibility issues in lower versions of IE and is rarely acceptable for application...
As Jens Roland already said, this is not possible through pure CSS.
Maybe LESS is helpful to you.