I have a strange problem that happens when I animate the width of a relative positioned element which contains an absolute element. While the animation is running, inner element dissapears. When the animation is complete, inner element shows.
Here is the demo:
http://jsfiddle.net/R4Cj5/
When I remove parent element position: relative then inner element is shown while animation is running, but then I can't position it relatively to the parent.
Basically box with the % should be visible al the time
Does anyone have any idea whats happening here?
FIXED : I just added overflow: visible !important; to relative
positioned element
working example : http://jsfiddle.net/R4Cj5/26/
I think it might be a jQuery animate thing. I would love to see a working solution without any hacks, but for now here is something you might find useful! :-)
I basically added another function in the animate, upon completion it will animate the 90% to hover above the progress-bar
complete: function() {
$percent.animate({top: "-26px"})
}
in this use-case scenario, you can also remove/comment out the top: -26px from .progressbar .percent in the stylesheet. Also I added height: 20px; to the styling for .progressbar .percentage so you could see the % change as it glides across.
Related
I am trying to determine the top/bottom padding of a div (.content) based on it's height, and to recalculate it based on load AND resize of the window. This is supposed to align nicely centered next to another div (.character) beside it.
I've tried using CSS calc, but in this case it doesn't do exactly what I want it to do since the syntax doesn't support operators and I have a few media queries that change the size of the font based on the viewfinder, so the height of the .content div is somewhat dynamic.
Below is the JS portion, but here is the JSFiddle of what I've done so far: https://jsfiddle.net/inochiishtal/a9z13fb2/62/
$(function(){
$.w = $(window);
$.w.on('load resize', res);
res();
});
function res() {
$('.content').css('height',($.w.innerHeight()/2)+'px');
}
Any help or suggestions are appreciated. I'm not 100% dedicated to using innerHTML if there is a better solution.
It's a little unclear exactly how you want the items aligned, but based on what you said it seems like you want the .content and the .character to be vertically center aligned with each other.
In your snippet you have both of them absolutely positioned. If that's the way you want to go, you can just ignore their margins and JavaScript in general with this little vertical centering trick applied to both:
top: 50%;
transform: translateY( -50% );
The first line says "Put the top of this element 50% of the way down the element that it's positioned based on." Since it goes by the top, the second line says "Scoot me back up 50% of my height." That's just the way those CSS properties work -- the "top" % is about its parent, and the translateY % is about itself.
Since both of your elements would be vertically centered in their parent, they'd be aligned.
https://jsfiddle.net/qowxezpy/
HOWEVER if you don't need the elements to overlap like they do in this example (which I think looks nice and modern) there's a much easier way, using flex.
The parent would get:
display: flex;
align-items: center;
And the two children get:
flex-basis: 50%; //just to give them some width, since one is empty
I have two divs nested inside of a div.
<div id='outter' class='one'>
<div id='inner'></div>
<div id='button' class='bttn'>Click me!</div>
</div>
The outter div's height is a percentage of the page. I'd like one of the inside div's height to be a fixed difference away the outter div (i.e. $('#inner').height($('#outter').height() - 35)), because the second inner div is essentially a button with fixed height (35). I'd like this to happen even when I change the height (through CSS triggers (:hover/adding a class/etc. so I can use Transitions) or otherwise).
I googled around a bit and saw Less might be an answer, but from what I can tell it compiles in to static values, but I still need to use percentages, since I want this app to work/feel the same on any screen size.
I have examples of what I'm currently doing/how I'm thinking about it in some jsfiddles.
Current 'solution': http://jsfiddle.net/L9NVj/5/ (End heights are what I want them to be, but the transition looks terrible)
Idealistic 'solution': http://jsfiddle.net/L9NVj/6/ (End heights are wrong, but the inner div hugs appropriately)
Potential solution: http://jsfiddle.net/L9NVj/7/ (This hides the inner div on click and then shows it again when the appropriate size has been reached)
Any help/thoughts/insights would be greatly appreciated!
Consider absolute-positioning the inner elements, since the outer's size isn't controlled by their size/position.
#inner {
position: absolute;
top: 2px;
left: 2px;
right: 2px;
bottom: 35px;
/* ... */
}
.bttn {
position: absolute;
bottom: 2px;
left: 2px;
/* ... */
}
Example: http://jsfiddle.net/L9NVj/9/
How about conflicting absolute positioning. To do it, you'd just need to set the top, bottom, left and right of the #inner element and then transition those. That will maintain the distances around the edges of the element, and allow other positioning as well.
Note that while you don't need to actually calculate the value in this case, in the future, calc() can be used to calculate a dynamic value in CSS. In that case, you could do something like height: calc(100% - 37px); to get the same effect.
CSS3's calc() is the answer you're looking for, in combination with a JavaScript fallback for browsers that don't support calc(). In your 'Idealistic solution' fiddle, change your CSS height definition to the following:
height: -webkit-calc(100% - 35px);
height: calc(100% - 35px);
While normally you should include all prefixes (and you still may need to, depending upon your level of browser support), according to Can I Use, the only browsers that currently need prefixing are -webkit browsers.
What I would do with this knowledge is the following: grab a feature detection script, I really like Modernizr and detect to see if calc() is available in the browser. Modernizr has a non-core detect for calc() that you can use. Use that CSS in your CSS file as the default, then using a resource loader such as yepnope (comes with Modernizr), load in a JS solution if calc() isn't available.
Of your JavaScript solutions, I'd probably suggest your "Potential Solution" option, but instead of jQuery's hide() and show(), set opacity to 0 and 1 and use a CSS3 transition to transition between the two. I'd also not rely upon a timeout, but rather use the transitionend JavaScript event.
I edited your first jsfiddle little bit i think that's what you wanted. Just added line.
$(window).resize(function(){$('#inner').height($('#outter').height() - 35)});
jsfiddle:http://jsfiddle.net/Qqb3g/
You may have to some workaround to make transition smooth when button the button is clicked.
you need to calculate the inner div in %, so it can resize belong outer div, change your js code to this :
//calculating inner div'x height in % of outer
$('#inner').height((100 - (33/$('#outter').height() * 100)) + '%');
$('#button').click(function () {
$('#outter').toggleClass('two');
});
give a try to DEMO
Here is the fiddle I'm working on: http://jsfiddle.net/fFYqF/
Basically it's a h1 above an h2 with some hidden paragraphs in-between them. This is all contained inside a div which I am trying to make visually centered (horizontally and vertically on the screen. I have used this css on the container div to center it on the page:
div#holder {
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
height:40%;
width:60%;
min-width:300px;
}
For this to work the width and the height of the div must be specified.
I have 2 problems... first, I don't know the height of the div so I have tried to use jQuery to apply it dynamically:
var h = $('#holder').height();
$('#main').css('height', h + 'px');
Secondly, I have a further bit of jQuery to animate the paragraphs of text open. This changes the height of the holder div thus rendering the earlier calculated height incorrect and the div is no longer vertically centered.
Is there a way to have the holder div always centered on the page? I.e. it should move up when it is opening.
Please see the fiddle above to see what I mean. Thanks
I have updated a branch of your fiddle to use a mixture of using .animate() with the height as well as the top position of the element to make it look like its opening up.
Have you tried the .animate method instead? I haven't tested this in a vertical-centered situation like you're describing, but I've used this method to increase the height of my containers when I'm bringing other elements into view.
$('#main').animate({height: '+='h }, 'slow');
I have this demo
However the mouse over when dragged to left or right stops the toogle.
The hover() event didn't solve the problem.
Any idea ?
div.fileinputs {
position: relative;
display: none;
}
#show {
width: 200px;
height: 40px;
background-color: red;
z-index: -2px;
position: absolute;
}
<div id="show"></div>
<div class="fileinputs">Visible Panel Div</div>
$('#show').mouseover(function() {
$('.fileinputs').toggle();
});
Given that you want to simply show the element on mouseover and then hide it on mouseout, you should also use mouseout() to define the desired behavior you want when the mouse is removed:
$("#show")
.mouseover(function(){
$(".fileinputs").toggle();
})
.mouseout(function(){
$(".fileinputs").toggle();
});
Example. (It's choppy because fileinputs is a separate element, and it's not counting hovering over that as hovering over the show div).
But you should use hover, just to make it easier:
$("#show").hover(function(){
$(".fileinputs").show();
}, function(){
$(".fileinputs").hide();
});
Example. (Choppy for the same reason as above).
Since your desired behavior is definite, we'll just use show() for when the mouse is over it and hide() when it is removed.
By the way, it is preferred that you bind events using delegate() (for older versions of jQuery) or on() (for jQuery 1.7+):
$(document).on("mouseover mouseout", "#show", function(){
$(".fileinputs").toggle();
});
Example.
Though, you really should just use CSS for this. You can place fileinputs inside of show and use a child selector:
#show:hover > .fileinputs {
display: block;
}
Example. This one doesn't flicker because the element is inside the one that's getting the hover declarations attached to it, and CSS considers it as though you are still hovering over the parent element (because you technically are, as the target of the hover is within the boundaries of the parent [it would still work if it was outside the boundaries because the element is still nested]).
I think it's because you set your z-index on show to be -2. Once the fileInputs div is visible, it becomes on top of show, and as a result, mouseover for show no longer responds.
If you notice, if you hover from left to right over the red show div, but just below where the text is, the fileinputs div does in fact toggle.
If you add a border around the fileinputs div, the cause of the behavior will be clearer.
See: http://jsfiddle.net/pS9L8/
Moving your cursor over the region where the two divs overlap triggers a mouseover event, showing the hidden fileinputs div. Since that div is now displayed on top of show, your cursor is no longer directly over the original show div. You then continue to move your cursor, and as it moves outside the fileinputs region, that move is seen as another entrance to the underlying show div. Which again triggers the .toggle(), re-hiding the fileinputs div.
One quick fix is to switch to the jQuery custom event mouseEnter instead of mouseover (although you may get some jerky artifacts as jQuery reasons about the meaning of "over"). Depending on what you're trying to achieve, another option would be to reorder the two divs by z-index.
I have coded my div to re size and change margin on click of a div with id = switch. But it is disappearing on beginning of animation and reappear on the completion of animation. Ypu can see my fiddle here. Why is this happening and how can I avoid this??
Thanks in advance...:)
blasteralfred
Add
overflow: visible !important;
to #sidebar and#switch won't disappear during the animation.
It is happening because it is hidden underneath your "viewer". If you can move your switch inside the "viewer" and float it left, set margin-left. Should fix it.
During the animation the elements overflow is set to "hidden".
As #switch is visually placed outside #sidebar it disappears. Christopher's solution should override it.
It also would'nt happen if you place #switch inside #viewer