Resize highchart based on container changing NOT window resize - javascript

Here's a code pen that illustrates the code I will place here: https://codepen.io/andrewsunglaekim/pen/MmmxvO
Don't mind the terrible html, I just copied a simple high charts demo.
The Html is simple:
<div class="flexContainer">
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
<div class='flexToggle'>Flex it</div>
</div>
Simple chart nested within a flex container.
The CSS:
.flexContainer {
display: flex;
}
#container {
transition: flex 0.5s ease;
flex: 3;
background: red;
}
.flexToggle {
transition: flex 0.5s ease;
flex: 1;
background: green;
}
#container.flexed {
flex: 1;
}
.flexToggle.flexed {
flex: 3;
}
Here's the simple jQuery script that toggles the flexed class:
$(".flexToggle").on("click", function(){
$("#container").toggleClass("flexed")
$(".flexToggle").toggleClass("flexed")
})
I want the chart to resize dynamically with the transitioning flex elements. Everything I've seen is a work around leveraging windows resizing, but I have no event like that in this case. Writing a setInterval to redraw during the transition seems hacky. Is there a configuration piece I'm missing that makes this really simple?

After some research, you can fix the horizontal scaling by simply adding
.highcharts-container, .highcharts-container svg {
width: 100% !important;
}
to the CSS

Related

Why does reflow need to be triggered for CSS transitions?

I was reading this article http://semisignal.com/?p=5298 and the author wrote that
"Reflow needs to be triggered before the invisible class is removed in order for the transition to work as expected. "
My questions are :
1) Why does reflow need to be triggered?
2) I understand that we should avoid using reflow, if that is true why is the author suggesting to use reflow in order to make the transition work?
3) Instead of using reflow, is there a different method to make the transition work?
Thank you.
(Effectively: "Why can't I easily use transitions with the display property")
Short Answer:
CSS Transitions rely on starting or static properties of an element. When an element is set to display: none; the document (DOM) is rendered as though the element doesn't exist. This means when it's set to display: block; - There are no starting values for it to transition.
Longer Answer:
Reflow needs to be triggered because elements set to display: none; are not drawn in the document yet. This prevents transitions from having a starting value/initial state. Setting an element to display: none; makes the document render as if the element isn't there at all.
He suggest reflowing because it's generally accepted to hide and show elements with display: none; and display: block; - typically after the element has been requested by an action (tab or button click, callback function, timeout function, etc.). Transitions are a huge bonus to UX, so reflowing is a relatively simple way to allow these transitions to occur. It doesn't have an enormous impact when you use simple transitions on simple sites, so for general purposes you can trigger a reflow, even if technically you shouldn't. Think of the guy's example like using unminified JavaScript files in a production site. Can you? Sure! Should you? Probably not, but for most cases, it won't make a hugely noticeable difference.
There are different options available that prevent reflowing, or are generally easier to use than the method in the link you provided. Take the following snippet for a few examples:
A: This element is set to height: 0; and overflow: hidden;. When shown, it's set to height: auto;. We apply the animation to only the opacity. This gives us a similar effect, but we can transition it without a reflow because it's already rendered in the document and gives the transitions initial values to work with.
B: This element is the same as A, but sets the height to a defined size.
A and B work well enough for fading in elements, but because we set the height from auto/100px to 0 instantly, they appear to collapse on "fade out"
C: This element is hidden and we attempt to transition the child. You can see that this doesn't work either and requires a reflow to be triggered.
D: This element is hidden and we animate the child. Since the animation keyframes give a defined starting and ending value, this works much better. However note that the black box snaps into view because it's still attached to the parent.
E: This works similarly to D but we run everything off the child, which doesn't solve our "black box" issue we had with D.
F: This is probably the best of both worlds solution. We move the styling off the parent onto the child. We can trigger the animation off of the parent, and we can control the display property of the child and animate the transition as we want. The downside to this being you need use animation keyframes instead of transitions.
G: While I don't know if this triggers a reflow inside the function as I haven't parsed it myself, you can just simply use jQuery's .fadeToggle() function to accomplish all of this with a single line of JavaScript, and is used so often (or similar JS/jQuery fadeIn/fadeOut methods) that the subject of reflowing doesn't come up all that often.
Examples:
Here's a CodePen: https://codepen.io/xhynk/pen/gerPKq
Here's a Snippet:
jQuery(document).ready(function($){
$('button:not(#g)').click(function(){
$(this).next('div').toggleClass('show');
});
$('#g').click(function(){
$(this).next('div').stop().fadeToggle(2000);
});
});
* { box-sizing: border-box; }
button {
text-align: center;
width: 400px;
}
div {
margin-top: 20px;
background: #000;
color: #fff;
}
.a,
.b {
overflow: hidden;
height: 0;
opacity: 0;
transition: opacity 3s;
}
.a.show {
height: auto;
opacity: 1;
}
.b.show {
height: 100px;
opacity: 1;
}
.c,
.d {
display: none;
}
.c.show,
.d.show {
display: block;
}
.c div {
opacity: 0;
transition: 3s all;
}
.c.show div {
opacity: 1;
}
.d div {
opacity: 0;
}
.d.show div {
animation: fade 3s;
}
#keyframes fade {
from { opacity: 0; }
to { opacity: 1; }
}
.e div {
display: none;
}
.e.show div {
display: block;
animation: fade 3s;
}
.f {
background: transparent;
}
.f div {
background: #000;
display: none;
}
.f.show div {
display: block;
animation: fade 3s;
}
.g {
display: none;
}
<button id="a">A: Box Height: Auto</button>
<div class="a">This<br/>Has<br/>Some Strange<br/><br/>Content<br>But<br>That doesn't really<br>Matter<br/>Because shown,<br/>I'll be<br/>AUTO</div>
<button id="b">B: Box Height: 100px</button>
<div class="b">Content For 2</div>
<button id="c">C: Hidden - Child Transitions (bad)</button>
<div class="c"><div>Content<br/>For<br/>3<br/></div></div>
<div style="clear: both;"></div>
<button id="d">D: Hidden - Child Animates (Better)</button>
<div class="d"><div>Content<br/>For<br/>4<br/></div></div>
<div style="clear: both;"></div>
<button id="e">E: Hidden - Child Hidden & Animates</button>
<div class="e"><div>Content<br/>For<br/>5<br/></div></div>
<button id="f">F: Child Has BG & Animates (Works)</button>
<div class="f"><div>Content<br/>For<br/>5<br/></div></div>
<div style="clear: both;"></div>
<button id="g">G: This uses fadeToggle to avoid this</button>
<div class="g">I animate with<br/>JavaScript</div>
<footer>I'm just the footer to show the bottom of the document.</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

How can I make this Jquery animate() with css3 animations?

This is my jfiddle
And this is my actual code
$card.animate({
left: "1000px"
}, 500, function(){
$card.hide(500);
});
(I dont know why 'left' didnt work on jfiddle) Basically ive got a container with 5 $cards there. When user swipes the card (already implemented) the animate() is triggered and the card slides to the rightand then disappears. How can I implement such thing in CSS animations instead of using Jquery? Ive read that CSS animations run faster (and I proved it on my mobile device, the hide() runs really slow)... Any help or advice will be appreciated
First of all, create a class that you can trigger via jQuery that will have the animation.
Then, using you have two options: transition or animation. Transitions are simpler and more direct, but you can do more with animations.
Here is how I would suggest to do it: a transition for the movement, and an animation to recreate the hide() function.
#keyframes hide {
99% { display: auto; }
100%{ display: none; opacity: 0; }
}
.myelement {
transition: all .5s;
position: absolute;
left: 0;
}
.myelement.toLeft {
left: 2000px;
animation: hide .5s 1 forwards;
}
To trigger it, simply do this:
$(".myelement").addClass("toLeft");
Here is a working JSFiddle.
And like #MohitBhardwaj said, it is necessary for you to set position to absolute, relative, or static in order for positioning (i.e., the left property) to work.
It's also important to note that a transition needs an initial value. I added left: 0 to do this. Otherwise, (with a CSS transition) it would simply jump to 2000px because there is no starting point.
Also, because 2000px as a left value is very large, I suggest you change the parent element's scroll to overflow: hidden, so that the extraneous scroll bar doesn't appear.
Your left didn't work, because you need to set position to a value other than static (which is default) for it to work.
As for using CSS, you can add a class instead of animating in jQuery. This class can change the transition which you can set in css as per your requirements.
var my_div = $('.myelement');
my_div.on('click', function() {
var $this = $(this);
$this.addClass("gone");
setTimeout(function(){
$this.hide();
}, 600 );
})
#mywrapper
{
overflow: hidden;
}
.myelement {
height: 200px;
width: 200px;
background-color: red;
opacity: 1;
position: relative;
transition: all 0.5s ease;
opacity: 1;
left: 0px;
}
.myelement.gone
{
left: 500px;
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="mywrapper">
<div class="myelement">
Click me please
</div>
</div>

Rotation and opacity causes text rendering issues in Firefox

I've run into an odd text rendering issue with Firefox. I have a div that is rotated, and another div inside it has it's opacity rapidly changed between 1 and 0.5. This causes any text inside the div to render differently each time the opacity changes - some numbers will shift up or down by a pixel, parts of the text will be thicker or narrower.
As an example, this:
<div class="outer">
<div class="glowyWrapper">
<div class="glowy transparent"></div>
</div>
<p class="someText">1 2 3 4 5 6 7 8 9</p>
</div>
With these styles:
.outer {
transform: rotate(1deg);
width: 300px;
height: 200px;
}
.glowyWrapper {
width: 100%;
height: 10%;
}
.glowy {
width: 100%;
height: 100%;
}
.transparent {
opacity: 0.5;
}
.someText {
font-size: 60px;
font-weight: 800;
text-align: center;
margin: 10px;
}
Adding a bit of javascript to repeatedly add and remove the "transparent" class will cause the rendering issue.
Here is a fiddle demonstrating the issue:
https://jsfiddle.net/projectx593/n01m1jop/10/
I have found a few workarounds, like decreasing the rate the opacity changes, or having it alternate between 0.95 but I'd rather not have to adjust the speed of it if possible, or have the flashing div be always transparent to some degree. Is there a better solution to this?
I found the issue in Firefox version 46.0
Since transform is already there and -moz-backface-visibility: hidden; useless you may use a filter to force FF render calculation, so you cure also the stair effect on edges.
filter: blur(0.1px);/* note that even 0 as value does it */
https://jsfiddle.net/n01m1jop/14/

Automatically Adjust Height Showing Slide Content

I am using angular and angular animate to hide and show content with a slide up/down effect - similar to jQuery show.
However, this worked well when i had one slide. Now i have multiple, with varying sizes, how can i adjust the code so the height of the element to show (div or form) is automatially calcuated and adjusted rather than being predefined?
HTML:
<h2 ng-click="showSpoons = !showSpoons">Show Spoons +</h2>
<div ng-show="showSpoons" class="animate-slide-up">
<p>Spoon</p><p>Spoon</p><p>Spoon</p>
<p>Spoon</p><p>Spoon</p><p>Spoon</p>
<p>Spoon</p><p>Spoon</p><p>Spoon</p>
<p>Spoon</p><p>Spoon</p><p>Spoon</p>
</div>
<br>
<h2 ng-click="showForks = !showForks">Show Forks +</h2>
<div ng-show="showForks" class="animate-slide-up">
<p>Fork</p><p>Fork</p><p>Fork</p>
<p>Fork</p><p>Fork</p><p>Fork</p>
</div>
<br>
<h2 ng-click="showCups = !showCups">Show Cups +</h2>
<div ng-show="showCups" class="animate-slide-up">
<p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p>
<p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p>
<p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p>
<p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p>
<p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p><p>Cups</p>
</div>
CSS:
.ng-hide-add, .ng-hide-remove {
/* ensure visibility during the transition */
display: block !important; /* yes, important */
}
.animate-slide-up {
transition: .25s linear all;
height: 10em;
overflow: hidden;
}
.animate-slide-up.ng-hide {
height:0;
}
Plunker: https://plnkr.co/edit/t7oVw3n3oTxuPaPLo38a?p=preview
You are pretty much defining a fixed height value for your slides. Instead of using fixed values, you may use height: auto;. This will provide your slide an automagically generated height value, according to the slides content. So basically, what you need is this:
.animate-slide-up {
transition: .25s linear all;
height: auto;
overflow: hidden;
}
plnkr
Use this,
.animate-slide-up {
transition: .25s linear all;
min-height: 10em;
overflow: hidden;
}

Change how fast "title" attribute's tooltip appears

Is there a way to change how fast the tooltip from an element's "title" attribute? I'd like it if the tooltip appeared immediately, but it seems to take a few seconds to appear.
No, there's no way. The title attribute is implemented in a browser dependent fashion. For example I remember differences between IE and FF when using \r\n inside it.
Mozilla's docs explain the limits and functionality well.
If you want customization you may take a look at third party plugins such as qTip2 which mimic it using divs and stuff and provide you full control.
You could use jqueryUI as suggested. An example of controlling the duration on the show property:
$( ".selector" ).tooltip({ show: { effect: "blind", duration: 800 } });
Jquery UI tooltip is extremely simple and customizable: Just download or include jquery UI in your page.
If you want all the tooltips of your page to show immediately at hover, just use this:
$(document).tooltip({show: null});
Note that this applies to all elements that have a 'title' attribute.
You can modify the selector to affect only a class, and set custom speed or effect:
$('.yourClass').tooltip({show: {effect:"none", delay:0}});
Unfortunately, there is no way to do this yet,
so I am using the following methods to help. (No dependencies required)
<style>
[title] {
position: relative;
}
[title]:after {
content: attr(title);
position: absolute;
left: 50%;
bottom: 100%; /* put it on the top */
background-color: yellow;
width: max-content;
opacity: 0;
-webkit-transition: opacity 0.75s ease-in-out; /* 👈 Change the time to meet your requirements. */
}
[title]:hover:after {
opacity: 1;
}
</style>
<div style="min-height:5rem"></div>
<div style="min-width: 5rem; border: 2px solid red;" title="hello world">my div</div>
<button title="for debug">button</button>
If you don't want the title to conflict with it, you can use data-* w3school.data-* help you, for example.
<style>
[data-tooltip] {
position: relative;
}
[data-tooltip]:after {
content: attr(data-tooltip);
position: absolute;
left: 50%;
bottom: 100%; /* put it on the top */
background-color: yellow;
width: max-content;
opacity: 0;
-webkit-transition: opacity 0.75s ease-in-out;
}
[data-tooltip]:hover:after {
opacity: 1;
}
div[data-tooltip]:after {
left: 5px!important;
}
</style>
<div style="min-height:5rem"></div>
<div style="min-width: 5rem; border: 2px solid red;" data-tooltip="hello world">my div</div>
<button data-tooltip="for debug">button</button>
<button title="for debug">title only</button>
<button data-tooltip="my tool tip msg" title="my title msg">title and tooltip</button>
below link may help you too.
fade in and out on simple css tooltip
It isn't possible to change how fast default browser's tooltip appear, but you can use one of the tooltip plugins (here is few: http://www.1stwebdesigner.com/css/stylish-jquery-tooltip-plugins-webdesign/ ) where you can customise lot's of things, including delay.
TippyJS has a billion customization options.
https://atomiks.github.io/tippyjs
https://github.com/atomiks/tippyjs

Categories