Panes inside kendoSplitter doesn't respect "box-sizing:border-box" property - javascript

I am using kendoSplitter to create a page layout with 2 panes.
Setting the first pane size as "100px" and the remaining space for 2nd pane.
Set the padding for the panes as "5px" and set the box-sizing as "border-box".
So,expected the width of pane1 including padding is "100px"
But on page load, it applied padding on top of 100px,making the width as 110px and leading to scrollbar.
$('#splitter').kendoSplitter({
panes:[
{collapsible:true,size:'100px'},
{collapsible:true,resizable:true}
]
});
jsFiddler for this case:
http://jsfiddle.net/nagakiran/xmTJF/
But if I apply the padding after initializing kendoSplitter,it works as in this fiddler.
http://jsfiddle.net/nagakiran/hPVWf/1/
Looks it's a bug in kendoUI or am I missing something?

I don't think it is a bug. Maybe an undocumented feature or a side-effect. It seems that is a question about the order on how things are executed.
Remember that you HTML is "decorated" by KendoUI widgets so what you have defined as splitter1 is not just your div but more things (the decoration).
When you style it after invoking kendoSplitter you are actually re-decorating the result of KendoUI decoration. Since kendoSplitter sets the width of your pane to a fixed width, the padding does not add extra space.
But when you use the CSS, it runs simultaneously to kendoSplitter and when it asks for the size, it gets the wrong size.
Should KendoUI be smarter? Maybe but it's actually pretty hard guessing what CSS are going to do and apply a counter action before the CSS.

Fixed it by adding a flag in kendoSplitter which modifies the way width is assigned to splitter panes. If this flag is set,it will reduce the width that's assigned to each pane by the "padding-left+padding-right" specified for that pane.
After that found a simple solution of creating wrapper div inside each splitter-pane and set "box-sizing:border-box" and "padding:10px", which worked without issues.

Kendo has issues with box-sizing: borderbox. This post may help.

Related

Aurelia JS - Kendo UI vertical sliders with height in percent?

I've taken a version of the code posted on Aurelia JS - iterate through children (kendo UI) elements? and modified it slightly, here:
https://gist.run/?id=323de53223d2ec872f17361378639556
I would basically like to express that the vertical sliders should be 90% of the height of the enclosing div; note that:
If there is no CSS height: specification, the sliders get some height, and that is it
If I set the CSS height (either via div.eqSlider in basic-use.css, or as an inline style attribute) in either px or em, then all is fine
But, if I set the CSS height in percent % (either via div.eqSlider in basic-use.css, or as an inline style attribute), or to calc(90%-10px) or similar - then the display is completely messed up, as shown on the image below:
So, is it somehow possible to set the height of these sliders to 90% of the height of the enclosing div - and if so, how?
Ok, I think I fixed it - the problem was as is typical in these cases: by default, divs and such don't have a height defined, and their height gets computed based on their contents. Since the sliders in the example are the content, without any other further specification, their height in procent then either becomes recursive, or is percentage of height 0.
Which is why then one must ensure that the entire chain from body to the enclosing div have a height defined in % (in essence, 100%, except it may show scrollbar). And I thought I had done that in the previous example - but I made a mistake in the .css: I used a .example selector (for a class), whereas I should have used #example selector (for an id); and that broke the height calculation of the chain of nested divs.
I noticed that once I assigned borders to each and every div in the nested chain; and then could correct so they all have defined height. Once all of the divs - and thus the enclosing one - have a height, then the sliders can get a height in percent, either in the .css file, or by assignment from JavaScript (via slider.wrapper.css("height", "50%");)
And so, the corrected code is now on:
https://gist.run/?id=fcfc066733ad903fa0575388a1637e4f
... and the output looks as expected:

Can I expand a div so the overflow-y:auto scrollbar doesn't clip the div content?

Similar question, without a great answer:
How can I include the width of "overflow: auto;" scrollbars in a dynamically sized absolute div?
I have a <div> of fixed height that acts as a menu of buttons of uniform width. Users can add/remove buttons from the menu. When there are more buttons than can fit vertically in the <div>, I want it to become scrollable - so I'm using overflow-y:auto, which indeed adds a scrollbar when the content is too large in y. Unfortunately, when the scrollbar shows up it overlaps the menu buttons, and adds a horizontal scroll bar as a result - the big problem is it just looks horrible.
Is there a "right" way to fix this? I'd love to learn some style trick to make it work right (i.e. the scrollbar sits outside the div rather than inside, or the div automatically expands to accommodate the scroll bar when necessary). If javascript is necessary, that's fine - I'm already using jQuery - in that case, what are the right events are to detect the scrollbar being added/removed, and how do I make sure to use the correct width in a cross-browser/cross-style way?
JSFiddle: http://jsfiddle.net/vAsdJ/
HTML:
<button type="button" id="add">Add a button!</button>
<div id="menu">
</div>
CSS:
#menu{
background:grey;
height:150px;
overflow-y:auto;
float:left;
}
Script:
$('#add').button().click(function(){
var d = $('<div/>');
var b = $('<button type="button">Test</button>');
d.appendTo($('#menu'));
b.button().appendTo(d);
});
First: To remove the horizontal scrollbar set overflow-x: hidden; as Trent Stewart has already mentioned in another answer.
CSS Approach:
One thing I have done in the past is to add a wider wrapping div around the content div to make room for the scrollbar. This, however, only works if your container width is fixed... and may need to be adjusted (by serving different styles) in various browsers due to variable rendering of scrollbars.
Here a jsfiddle for your case. Note the new wrapper <div id="menu-wrap"> and its fixed width width: 95px;. In this case the wrapper div is doing the scrolling.
You could probably also solve this by giving the wrapper some padding on the right, and thereby avoid the fixed width problem.
jQuery Approach:
Another option is to detect the overflow using jquery as described here, and then increasing the width or padding of the div to make space. You may still have to make browser-specific adjustments though.
Here a jsfiddle with a simplified version for your example. This uses your click function to check the div height after every click, and then adds some padding to make room for the scrollbar; a basic comparison between innerHeight and scrollHeight:
if($('#menu').innerHeight() < $('#menu')[0].scrollHeight){
$('#menu').css( "padding", "0 15px 0 0" );
}
To make this more cross-browser friendly you could check for the scrollbar width (as outlined here) and then add the returned value instead of the fixed padding. Here another jsfiddle to demonstrate.
There are probably many other methods, but this is how I would go about it.
Have you tried simply using overflow-x: visible; or hidden

Position an element at the bottom of a floating div with unknown height

I am currently trying to position an element in a way that it always is at the bottom of it's parent. What's special here is that none of the heights or widths are known. I'd like to do this without tables, if at all possible (my superior is against using those. In a very religious way).
I tried the approach of using position:relative on the parent and position:absolute; bottom:0; on the box I want to have at the bottom. This, however, causes the box to overlap with the other content of the parent div since absolute positioning causes the parent to ignore the height of the positioned element. Some JavaScript is used to align the heights of the floating divs to each other. But disabled JavaScript should not completely break the layout (as in: cause content to overlap or break the "flow" of the page).
Here's the fiddle with the exact structure of my markup: http://jsfiddle.net/vbeC2/27/
I did read the "float: bottom" question on SO, but none of the answers really adressed my problem, hence the new question.
It's not the cleanest solution, but since you were already using the maxHeight bit to calculate the sizes, I just added a second each loop to check the max-height of the bottom section, and added it, so that the relative, absolute positioning would work.
http://jsfiddle.net/robsterlini/svcGB/ or http://codepen.io/robsterlini/pen/BcDyt
EDIT When you resize your browser it won't work, but you could just add a resize event that recalculated it, and you'd need to think about creating some javascript-less fallbacks, either using modernizr, or just some simple
Please find the working demo here: JS Enabled
Modified the jquery logic to calculate the height of the maximum height of the container as shown below:
$(document).ready(function(){
//Set the height of the columns to the highest value of all columns
var maxHeight = 0;
$(".same-height").each(function(){
var k = $(this).children('.headline').innerHeight() + $(this).children('.description').innerHeight()+$(this).children('.bottom').innerHeight();
maxHeight = Math.max(maxHeight,k);
});
$(".same-height").css({"height" : maxHeight});
});
If JavaScript is disabled then you should apply different styles as shown in demo here:
JS Disabled
Here is something similar to what you want to atchive but the demo is centering the
http://css-tricks.com/centering-in-the-unknown/
You should use the same trick : using css ::after/::before pseudo classes to set your footer content in your parent div

Applying position:absolute to a style via jQuery fails to center div horizontally upon first page load

This is a followup to my question here. I would like to understand why applying position:absolute to the CSS of a div via jQuery fails, while applying it in a static style works. Here are two jsfiddle examples:
Works: http://jsfiddle.net/jasper/Ty6Af/2/
No worky: http://jsfiddle.net/Ty6Af/3/
Note that the only difference between the two is where I apply position:absolute. Vertical centering always works, but horizontal centering does not work when the page loads for the first time. If you manually re-size the window the div will center correctly.
All of my testing has been on Chrome under Ubuntu thus far.
Anyway, I'm just now delving into the world of web development and these are exactly the kinds of 'quirks' that I need to begin understanding.
EDIT:
#Jasper found something interesting. If you make two calls to .css(), first applying position and subsequently applying a margin, it works. I would love to understand why. Here is an example: http://jsfiddle.net/jasper/Ty6Af/5/
So the issue is with how the width of the div is calculated by the browser depending on its position.
If the div is set to position : static (by default) then it's width is 100% of it's parents width and the element is not allowed to move around the page.
If the div is set to position : relative then it's width is 100% of it's parents width but it can be moved around with left.
If the div is set to position : absolute then its width is determined by the actual content of the div, for instance if there is only a 200px wide <span> element within the div then the div will be 200px wide.
You can test these observations by changing the CSS of your jsfiddle to specify position : relative (etc...) and remove the JavaScript that makes the div position : absolute, then use your Developer Tools to inspect the element and it's calculated width.
The problem with your code is that it sets the position : absolute at the same time it sets the margin of the element by using its width/height (which are calculated differently depending on the position of the element).
If you want to set the position of the div in JavaScript then you can do something like this:
$(function() {
//notice I cached the selector so it can be used in the future as well as set the position of the div
$signuparea = $('#signuparea').css({position : 'absolute'});
$(window).resize(function() {
$signuparea.css({
'margin-top' : '-' + Math.round($signuparea.height() / 2) + 'px',
'margin-left' : '-' + Math.round($signuparea.width() / 2) + 'px',
});
}).trigger('resize');
});
Here's a jsfiddle: http://jsfiddle.net/jasper/Ty6Af/8/
I believe the problem is that when you apply your left and right in your second fiddle, you have yet to add position absolute to the div. Hence, the browser has no idea what do with the left and right values and ignores them initially.
Practically speaking in your second fiddle, you only actually add the position:absolute on the resize trigger. So before you resize your actual div has no positioning.
If you instead add the position absolute on load it works fine:http://jsfiddle.net/Ty6Af/9/
Notice that if you give it position:relative from the start (like this http://jsfiddle.net/Ty6Af/11/ ) it allready applies both the left and right value. The reason you can't actually see the effect of "left" is because it is a block element.
I hope that answers your question, I'm not quite clear on where you are stuck.
http://jsfiddle.net/Ty6Af/7/ this should work, the trigger function in jquery has bugs with chrome so you have to run the function on load too.
The problem seems to be that position:absolute; negates the current layout and requires you to position it.....
See: http://jsfiddle.net/ZHaRD/
Which Jasper explains much more eloquently than myself!

Javascript clientHeight and alternatives

I am currently trying to modify a Javascript function that "slides in" a <div>. The script as it is requires you to define the height of the div, so it is mostly useless in dynamically filled <div>s. I found some text on the clientHeight property in javascript, but it would appear that it doesn't support <div>s with display set to none (which is the method used to slide the div in). That makes sense, as the height of that div in the client window is nothing.
Basically I was wondering what other methods you all know of, or if there's a way to get around the clientHeight = 0 when display: none.
Thanks!
Oh, and here's the function I'm using:
function getDivHeight(objName) {
return boxHeight = document.getElementById(objName).clientHeight;
}
A simple solution is to set it's visibility to "hidden" and it's display to "block" and measure it. However, some modern browsers will manage to update the page layout during this short time and you will get a nasty flicker. The easiest way to overcome this is to place the element in an absolutely positioned container with overflow set to "hidden".
I've had luck cloning the element, moving it offscreen, then displaying it to get the client height:
var original = document.getElementById(some_id);
var new_item = original.cloneNode(true);
document.body.appendChild(new_item); // item already hidden, so it won't show yet.
// you may wish to validate it is hidden first
new_item.style.position = "absolute";
new_item.style.left = "-1000px";
new_item.style.display = "block";
var height = new_item.clientHeight;
EDIT: Looking through the jQuery code, they do exactly what Tsvetomir Tsonev suggests. jQuery temporarily sets the style to "display: block; position: absolute; visibility: none", and then measures the height, swapping the properties back after the measurement.
So, it looks like you're stuck with having to do something hackish, whether it's cloning the node or risking having it flicker in some browsers... I like Tsvetomir's suggestion better than my initial hack as it, at least, doesn't involve cloning a node into the DOM that you don't need. Either way, the element must not be set to "display: none" in order to measure it's height. Isn't the DOM wonderful? :-)
EDIT 2: Also worth noting that, after jQuery gathers the height, it adds allowances for padding, margin and border sizes, so you may need to as well.
Yes, an element that is not displayed on the page has no dimensions.
It kind of makes sense. Consider an element that has been created and filled with a bunch of text, but not yet added to the document tree. How high is it? Depends on font-size. How big is font-size? Depends where in the document that div is inserted; its parent font-size would inherit through.
Similarly for an element with “display: none”. It's not rendered, so it has no dimensions. Couldn't we ask “how high would this be if it were ‘display: block’”? Turns out no, because if it were displayed, that in itself could change the dimensions of its parent block, and then the dimension of displayed elements would be inconsistent with the dimensions of non-displayed elements!
The typical solution is to unset “display: none”, measure the height of the element, and then immediately re-set “display: none”. The browser won't redraw in the middle of a bit of JavaScript, so you won't see a flicker on the page.
I nkow you guys solved this a long time ago but I thought I should share this since it quite tricky to get the height of a hidden div tag.
heres what I did after reading your post,
I placed the div i want to slide inside a 1px height div with overflow set to hidden.
you dont even need to set the display of the inner div to none since it is already there and if you use offsetHeight it should return the proper height for all browsers and you can use that height to slide your div up an down.
PEACE!!!
In IE you could try scrollHeight, but I'm not sure if it will work or if it is cross browser.

Categories

Resources