Does IE/Edge animate calc() CSS specs appropriately? - css

Demonstration Link: https://codepen.io/jodriscoll/pen/wRpQOw
I'm working on a "sidewards blind-like" animation behavior, where when a user hovers over an object (anchor), it expands the object (anchor) in width and creates a perception of showing more of the objects contain within (think of a clipping mask of sorts).
Initially the video/image object is styled in a way to prevent it from moving 1:1 with the "clipping mask" (anchor wrapping the video/image). Meaning, it is already offset to the position it should be when the user hovers over the anchor.
Both the image and the video are initially styled to fill the entirety of the anchor AND the gutter gaps; this helps when animating to create the perception that we're just showing more of the photo, no actually resizing it and causing it to move on screen (sorry, that might be confusing...):
left: -24px; // the width of each gutter gap
width: calc(100% + 48px); // fill the parent + fill the gutter gaps
When the user hovers over the anchor, the child elements change their CSS specs to:
left: 0; // stay flush with the anchor object
width: 100%; // fill the parent, which now includes the gutter gap(s)
Everything appears to work correctly when viewing the animation behaviors on Chrome / Safari / Firefox:
http://svg-gmmb-cis.pantheonsite.io/wp-content/uploads/2019/01/debugging_animations.mp4
Unfortunately, there is a slight hiccup on IE11/Edge:
http://svg-gmmb-cis.pantheonsite.io/wp-content/uploads/2019/01/IE_animation_bug.mp4
Questions and hopeful helpful insight towards reaching an answer:
After viewing the animation glitch, does IE11/Edge have issues with animating CSS measures using calc()?
Do I need to create a CSS animation with keyframes to remedy this hiccup in IE11/Edge?
Am I approaching this wrong and should be animating different properties?

You can do this easily with margin and avoid the use of calc.
Here is a simplified example:
.container {
border:1px solid;
padding: 0 24px;
height:100px;
}
.box {
height:100%;
background:red;
transition:.5s all;
}
.box:hover {
margin:0 -24px;
}
<div class="container">
<div class="box"></div>
</div>
Or like this:
.container {
border:1px solid;
margin: 0 24px;
height:100px;
}
.box {
height:100%;
background:red;
transition:.5s all;
}
.box:hover {
margin:0 -24px;
}
<div class="container">
<div class="box"></div>
</div>

Related

Use CSS to animate a box to fill a whole screen without any abrupt jumping

I have the following code which just draws a yellow box 80vh from the top of a container:
<!DOCTYPE html>
<html>
<head>
<style>
:root {
--t: 1s;
}
body {
padding:0;
margin:0;
}
.contain {
position:relative;
height:400vh;
background:blue;
}
.box {
position:absolute;
top:80vh;
height:400px;
width:50vw;
left:0;
background:yellow;
transition: position 0s linear var(--t),
background var(--t) ease 0s,
top var(--t) ease 0s,
height var(--t) ease 0s,
width var(--t) ease 0s;
}
input {
display:none;
}
input:checked ~ .contain .box {
position:fixed;
background: pink;
top:0;
height:100vh;
width:100vw;
}
</style>
</head>
<body>
<input id="checkbox" type="checkbox" />
<div class="contain">
<label class="box" for="checkbox"></label>
</div>
</body>
</html>
I want a CSS only solution where by if I click on the yellow box, it will smoothly grow to fill the whole screen without any abrupt jumping effect. My solution above works if your browser scroll position is at 0px (ie. at the top of the page). But the moment you scroll say 100vh down, clicking on the yellow box causes it to jump downwards a bit before it grows, which I clarify in this 30 second video: https://www.youtube.com/watch?v=2hVNg-OPZ6Q .
Can anyone suggest how I can use CSS and HTML only to achieve a smooth transition for my yellow box to grow and fill the entire screen?
I am afraid what you're trying to achieve is not 100% possible with a css-only solution.
As the other answer stated, the main issue comes from the fact you're going to a fixed position from an absolute one. The thing is that the position property is not animatable, meaning that no matter how many seconds you apply to it in the transition property, it will have no effect.
The closest css-only solution would be to do that :
/* Some code */
input:checked~.contain .box {
background: pink;
top: 0;
height: 100%;
width: 100%;
}
/* Some code */
The box will animate to fill the whole viewport but with a slightly different animation time to fill the whole height. Also the animation will start from the initial yellow box position and not from the bottom of the screen.
If you want to animate exactly how you described it in your post, you will necessarily have to use some javascript.
Reason behind the abrupt jumping effect is that in input:checked you have fixed position change it to absolute.
position:absolute;
Fixed position makes the element's position and dimension relative to its containing block that is the contain class whereas in absolute it is relative to initial containing block which is normally viewport: the browser window or the paper’s page box.

Make second div appear above first, without absolute position or changing html

My page is split into 3 slices, as shown in this JFiddle.
In my full source code, I have media queries to help manage sizing between mobile and desktop. When someone accesses the site on mobile mode, Logo should appear at the top, and Items should appear below it. (I set display: none on my picture div to hide it)
Problem:
I can't change the positioning of the divs in HTML, or it'll disturb my current 3 slice layout. Absolute positioning is not an option, since most of my site is already dynamically sized, and I wouldn't want absolute positioning to interfere on a resolution I haven't tested on. This means calculating the margin sizes would be out of the question aswell.
So, absolute positioning is not allowed, nor is changing the orders of the divs. The result I'm looking for would be similar to this, exception without repositioning the divs.
My question is not about media queries, or how to size for mobile using media queries. I am only asking about how to get the layout I want with the restrictions in place (no absolute positing, no calculating margins, no changing div order).
Other questions I looked at:
Reposition div above preceding element - First answer suggests repositioning divs, which I cannot do. Second answer relies on calculating the position, which could interfere with other dynamically sizing elements.
Move The First Div Appear Under the Second One in CSS - Suggests I use absolute positioning, which I cannot do
Flexbox layout is your friend here. display: flex can be used to interchange the elements position on the layout.
#container { display:flex; flex-direction: column; text-align:center;}
#items { order: 2 }
#logo { order: 1 }
#picture { display: none; }
<div id="container">
<div id="items">Items</div>
<div id="logo">Logo</div>
<div id="picture">Picture</div>
</div>
display: flex works only in modern browsers. Check caniuse.
A test on my android mobile shows it working on Firefox and Chrome, but not on the stock Android browser.
I tried to solve the solution using transform: translateY property in percentage value.
Note: This works if and only if the two containers have same height. or if the height is already known, then you can set the transform: translateY value according to the height.
CSS
#media (max-width: 700px) {
#container > div {
width: auto;
display: block;
float: none;
}
#container #picture {
display: none;
}
#logo {
transform: translateY(-100%);
}
#items {
transform: translateY(100%);
}
}
Working Fiddle
Probably the easiest is if you play with minus margins. Note that the below sizes (width and side margins) may need to be adjusted to your specific needs.
#container * {
width: 95vw;
text-align: center;
}
#items {
width: 50%; /* #picture is hidden so we split the screen into 2 */
float: left;
margin-top:30px; /* has to be smaller than the absolute of #logo */
margin-left:25%; /* half of the element's width */
}
#logo {
width: 50%; /* #picture is hidden so we split the screen into 2 */
float: right;
margin-top:-40px; /* its absolute has to be greater than the one of #items */
margin-right:25%; /* half of the element's width */
}
#picture {
width: 33%;
float: right;
display:none; /* Hiding #picture as you said you would */
}
<div id="container">
<div id="items">Items</div>
<div id="logo">Logo</div>
<div id="picture">Picture</div>
</div>

css3 pie not working on dynamic css change

I'm using css3 PIE in order to create circle through border-radius(in IE8). It is working fine normally.
but when i'm trying to change the background color of circle, that element is turning into square.
my code looks like this.
.menuIco {
width:16px;
height:16px;
border-radius:8px;
position:relative;
z-index:101;
background-color:#38B6E7;
}
.active .menuIco {
background-color:#F1F1F1;
}
my html looks like this..
<div> <!-- i am adding .active class to this div using jquery -->
<div class="menuIco"> </div>
</div>
when i add active class to parent div(using Jquery dynamically) the menuIco (circle) should change its color. But the border-radius property is collapsing.
can anyone help me how to fix this!
Thanks in advance.
Set your border-radius to 100%.
Here's a LIVE DEMO for you to see.
.menuIco {
width:100px;
height:100px;
border-radius:100%;
position:relative;
z-index:101;
background-color:#38B6E7;
}
I have made the width and height to 100px so as to show it on a larger scale. (this can be resized as necessary)
EDIT
Depending on your browser, you should look to include the other prefixes, is shown in this fiddle
the border radius is defined by:
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
border-radius: 100%;

Custom webkit scrollbar position

I have a custom webkit scrollbar like this:
::-webkit-scrollbar{
background: transparent;
width: 10px;
}
::-webkit-scrollbar-thumb{
background: #999 !important;
}
So it renders a grey custom scrollbar instead of the standard one. However, it is stuck to the right side of the page. I know I can change this by adding a margin, padding or border to my body but I am using fullscreen (on backgrounds) images. So when I try this all the images are affected by this too, which I do not want. So I tried to position the scrollbar but this does not work (as it is not an element but a user agent property...
So I'm looking for a way (without using another plugin) to customize the toolbar so that it is offset from the side.
Or, if possible that I can make the scrollbar offset in a div.
Secondly, I'm looking for a way that I can make the "track" of the scrollbar transparet. So only a handle.
Thanks in advance!
If you are still looking for for the answer (or somebody else is, like I was) - here is a definitive article about webkit scrollbars.
Answering Your first question - I'd suggest that you put all your scrollable content in a div with 100% height and 90% width - the 10% left on the right would be your offset. Like that:
.superDiv{
height:100%;
width:90%;
position:fixed;
}
body{ overflow: hidden }
The second question - you're looking for
::-webkit-scrollbar-track-piece {
background:transparent;
}
But as Apple people are pushing for no-scrollbar web browsing, only the properties set by CSS are visible, so you don't have to change the track-piece.
Clever solution I found recently was to put the border on the right hand side of the screen / div that contains scrollbar:
<div class="yourdiv">
border-right: 5px solid #(background_color);
</div>
An easy way to control the position of a custom scrollbar is to set the scrolling element (body?) using definitive positioning. You'll also need to set html to overflow:auto;
To make the thumb transparent, use a RGBa value for declaring the color. In this case I used 0,0,0,0.4 (red,green,blue,alpha). RGBa is not supported in every browser, Chris Coyier has a good table of who supports it here: http://css-tricks.com/rgba-browser-support/
If all you want to show is the thumb than also consider hiding the other elements of the scrollbar: resizer, scrollbar-button, and scrollbar-corner.
html {
overflow: auto;
}
body {
position: absolute;
top: 20px;
left: 20px;
bottom: 5px;
right: 20px;
overflow: scroll;
}
::-webkit-scrollbar{
background: transparent;
width: 10px;
}
::-webkit-scrollbar-thumb{
background: rgba(0,0,0,0.4); /*-- black at 40% opacity --*/
}
::-webkit-resizer,
::-webkit-scrollbar-button,
::-webkit-scrollbar-corner { display: none; }
Check out the working demo at http://jsfiddle.net/Buttonpresser/G53JQ/

Transparent div problem

Hey i have this div that shows as a popup:
<div class="popup">
</div>
Then with jquery i add another class to it to give it with the css associated to that class, position, size, color and transparency:
.show {
position: absolute;
color: #F4F5F6;
width: 600px;
margin-left: -300px;
height:300px;
background: #000000;
left:50%;
top:200px;
filter:alpha(opacity=95);
-moz-opacity: 0.95;
opacity: 0.95;
}
My problem is this:
I'm adding text and image to the div.
ending up like:
<div class="popup show">
<div class="image">
<img scr="blabla.png">
</div>
<div class="text">
ble ble ble
</div>
</div>
My problem is the following, even though i have overriden the opacity here:
div.image
{
position: relative;
float:left;
width:202;
height:402;
filter:alpha(opacity=100);
-moz-opacity: 1;
opacity: 1;
}
The image still apears with transparency.
Is there anyway to override the opacity values without having to put the image div outside of the popup div?
Since the '.show' class has an opacity of 95%, so will all of its descendants. It's unfortunate, but that's how opacity works. The descendants cannot overcome their ancestor's opacity as long as they still truly remain descendants.
You'll have to either set the '.show' background with a semi-transparent png or result to some awkward html (see: Non-Transparent Elements Inside Transparent Elements)
Not trying to be jerky, but this Google search (or something similar) might help
Try this:
div.image
{
position: relative;
float:left;
width:202;
height:402;
filter:alpha(opacity=100) !important;
-moz-opacity: 1 !important;
opacity: 1 !important;
}
http://www.w3.org/TR/CSS2/cascade.html#important-rules
EDIT: sorry; I've even come across this before and didn't twig. I think that the nested element's maximum opacity is the same as the outer element's opacity; you can never get more opaque than your parent element! Last I checked this is a proper CSS issue, and I don't know a workaround.
As a workaround, you could try not making nested, but use some ucnning positioning trickery.

Resources