How can i tell if a css property such as width ex: width:100% has px or % assigned to it.
in chrome for example if i have width:250px; and i do $('div').width() i get 250 whereas if i use percentage, i just get the width in px for the percentage based on my screen resolution.
This should work.
var value = $('#id').get(0).style.width;
var hasPx = value.indexOf('px') >= 0;
var hasPct = value.indexOf('%') >= 0;
JSBin: http://jsbin.com/asewit/2/edit#javascript,html
If by "css property" you mean css rule, and not inline style property set directly in the element, there is no fast way to get it. You'd have to:
Query all css rule declarations
Loop through every css rule and check if the element matches the
rule and push it into array
Loop through the candidates and take the latest width value, or the
latest width value with !important
If you mean inline style, it's so trivial it's hard to understand why the question got so many upvotes:
element.style.width and check if there is a px or % there
edit: here is incomplete demo for the css rule querying:
http://jsfiddle.net/Chjnd/1/
tested in google chrome and firefox
You can use .style.cssText, which contains the actual CSS code:
$("<div style='width:50px'>").get(0).style.cssText // "width: 50px; "
$("<div style='width:50% '>").get(0).style.cssText // "width: 50%; "
Related
I have a stylesheet which defines default width for images. When I read the image width style with jQuery width() it returns the right width. It also returns the same width when I call css("width"). But if there is no width defined in the stylesheet the function css("width") will also return the computed width() value but won't say undefined or auto or something like that.
Any ideas how I could find out if style is or is not defined in the CSS code?
Solution works for me cross browser. Thanks to everyone for helping:
$(this).addClass("default_width_check");
var width = ($(this).width() == 12345) ? 'none-defined' : $(this).width();
var height = ($(this).height() == 12345) ? 'none-defined' : $(this).height();
$(this).removeClass("default_width_check");
.default_width_check {
width: 12345;
}
I have a workaround idea that might work.
Define a class named default_width before all other style sheets:
.default_width { width: 1787px }
/* An arbitrary value unlikely to be an image's width, but not too large
in case the browser reserves memory for it */
to find out whether an image has a width set:
Clone it in jQuery: element = $("#img").clone()
give the cloned element the default_width class: element.addClass("default_width")
If its width is 1787px, it has no width set - or, of course, is natively 1787px wide, which is the only case in which this method will not work.
I'm not entirely sure whether this will work, but it might. Edit: As #bobince points out in the comments, you will need to insert the element into the DOM for all classes to be applied correctly, in order to make a correct width calculation.
No, the getComputedStyle() method on which jQuery's css() function depends cannot distinguish between an width computed from auto vs explicit widths. You can't tell if there was something set in the stylesheet, only from direct inline style="width: ..." (which is reflected in the element's .style.width property).
currentStyle works differently and will give you auto, however this is a non-standard IE extension.
If you really wanted to work it out, you could iterate over document.styleSheets, reading each of their declarations, getting the selector out and querying it to see whether your target element matched, then seeing if it contains a width rule. This would, however, be slow and not at all fun, especially as IE's styleSheet DOM differs from the other browsers. (And it still wouldn't cope with pseudo-elements and pseudo-classes, like :hover.)
You can use image.style.width (image should be your element). This returns an empty string if it's not defined in CSS.
You can check the element's style.cssText if the width is defined;
<img id="pic" style="width:20px;" src="http://sstatic.net/ads/img/careers-ad-header-so.png" />
var pic = document.getElementById('pic');
alert(pic.style.cssText);
But please note of the following styles
border-width: 10px;
width: 10px;
you should only match the width not the border-width.
I need to get the height of a textarea. Seemingly so simple but it's driving me mad.
I have been researching for ages on stackoverflow with no luck: textarea-value-height and jquery-js-get-the-scrollbar-height-of-an-textarea and javascript-how-to-get-the-height-of-text-inside-of-a-textarea, among many others.
This is how it looks currently:
This is how I want it to look, open a full height:
.
Here is my html:
<textarea id="history" class="input-xxlarge" placeholder="Enter the content ..." rows="13"></textarea>
CSS:
.input-xxlarge {
display: inline-block;
height: auto;
font-size: 12px;
width: 530px;
resize: none;
overflow: auto;
}
jQuery:
var textarea = $('#history');
I've tried (inter alia):
1. textarea.height() --> always returns 0
2. textarea.ready(function() { // wait for DOM to load
textarea.height();
}
3. getting scrollheight from textarea as an HTMLTextareaElement (i.e. DOM Element) --> returns 0
4. var contentSpan = textarea.wrapInner('<span>');
var height = contentSpan.height(); --> always returns 0
Please help, I'm at my wit's end!
Ok, I've found a solution. Whether it's the best solution, I don't know, but it works and that, frankly, is all I care about, having spent almost a day on this issue.
Here it is for anyone who faces the same problem:
Select the textarea:
var textarea = $('#history');
Get the textarea's text:
var text = textarea.text();
Create a temporary div:
var div = $('<div id="temp"></div>');
Set the temp div's width to be the same as the textarea. Very important else the text will be all on one line in the new temp div!:
div.css({
"width":"530px"
});
Insert the text into the new temp div:
div.text(text);
Append it to the DOM:
$('body').append(div);
Get the height of the div:
var divHeight = $('#temp').height();
Remove the temp div from the DOM:
div.remove();
Had a similar issue, in my case I wanted to have an expand button, that would toggle between two states (expanded/collapsed). After searching also for hours I finally came up with this solution:
Use the .prop to get the content height - works with dynamically filled textareas and then on a load command set it to your textarea.
Get the inner height:
var innerHeight = $('#MyTextarea').prop('scrollHeight');
Set it to your element
$('#MyTextarea').height(innerHeight);
Complete code with my expand button(I had min-height set on my textarea):
$(document).on("click", '.expand-textarea', function () {
$(this).toggleClass('Expanded');
if($(this).hasClass('Expanded'))
$($(this).data('target')).height(1);
else
$($(this).data('target')).height($($(this).data('target')).prop('scrollHeight'));
});
Modern answer: textarea sizing is a few lines of ES6 implementable two primary ways. It does not require (or benefit from) jQuery, nor does it require duplication of the content being sized.
As this is most often required to implement the functionality of auto-sizing, the code given below implements this feature. If your modal dialog containing the text area is not artificially constrained, but can adapt to the inner content size, this can be a perfect solution. E.g. don't specify the modal body's height and remove overflow-y directives. (Then no JS will be required to adjust the modal height at all.)
See the final section for additional details if you really, truly only actually need to fetch the height, not adapt the height of the textarea itself.
Line–Based
Pro: almost trivial. Pro: exploits existing user-agent behavior which does the heavy lifting (font metric calculations) for you. Con: impossible to animate. Con: extended to support constraints as per my codepen used to explore this problem, constraints are encoded into the HTML, not part of the CSS, as data attributes.
/* Lines must not wrap using this technique. */
textarea { overflow-x: auto; white-space: nowrap; resize: none }
for ( let elem of document.getElementsByTagName('textarea') ) {
// Prevent "jagged flashes" as lines are added.
elem.addEventListener('keydown', e => if ( e.which === 13 ) e.target.rows = e.target.rows + 1)
// React to the finalization of keyboard entry.
elem.addEventListener('keyup', e => e.target.rows = (elem.value.match(/\n/g) || "").length + 1)
}
Scrollable Region–Based
Pro: still almost trivial. Pro: animatable in CSS (i.e. using transition), though with some mild difficulty relating to collapsing back down. Pro: constraints defined in CSS through min-height and max-height. Con: unless carefully calculated, constraints may crop lines.
for ( let elem of document.getElementsByTagName('textarea') )
elem.addEventListener('keyup', e => {
e.target.style.height = 0 // SEE NOTE
e.target.style.height = e.target.scrollHeight + 'px'
})
A shocking percentage of the search results utilizing scrollHeight never consider the case of reducing size; for details, see below. Or they utilize events "in the wrong order" resulting in an apparent delay between entry and update, e.g. pressing enter… then any other key in order to update. Example.
Solution to Initial Question
The initial question specifically related to fetching the height of a textarea. The second approach to auto-sizing, there, demonstrates the solution to that specific question in relation to the actual content. scrollHeight contains the height of the element regardless of constraint, e.g. its inner content size.
Note: scrollHeight is technically the Math.max() of the element's outer height or the inner height, whichever is larger. Thus the initial assignment of zero height. Without this, the textarea would expand, but never collapse. Initial assignment of zero ensures you retrieve the actual inner content height. For sampling without alteration, remove the height override (assign '') or preserve (prior to) then restore after retrieval of scrolllHeight.
To calculate just the height of the element as-is, utilize getComputedStyle and parse the result:
parseInt(getComputedStyle(elem).height, 10)
But really, please consider just adjusting the CSS to permit the modal to expand naturally rather than involving JavaScript at all.
Place this BEFORE any HTML elements.
<script src="/path/to/jquery.js"></script>
<script>
$(document).ready(function(){
var textarea = $('#history');
alert(textarea.height()); //returns correct height
});
</script>
You obviously do not have to alert it. I was just using an easily visible example.
Given a textarea with an id of "history", this jQuery will return it's height:
$('#history').height()
Please see a working example at http://jsfiddle.net/jhfrench/JcGGR/
You can also retrieve the height in pixels by using $('#history').css('height'); if you're not planning on doing any calculations.
for current height in px:
height = window.getComputedStyle(document.querySelector('textarea')).getPropertyValue('height')
for current width in px:
width = window.getComputedStyle(document.querySelector('textarea')).getPropertyValue('width')
change 'textarea' to '#history' or like a css selector. or textarea, since a variable is declared to select element.
I have a stylesheet which defines default width for images. When I read the image width style with jQuery width() it returns the right width. It also returns the same width when I call css("width"). But if there is no width defined in the stylesheet the function css("width") will also return the computed width() value but won't say undefined or auto or something like that.
Any ideas how I could find out if style is or is not defined in the CSS code?
Solution works for me cross browser. Thanks to everyone for helping:
$(this).addClass("default_width_check");
var width = ($(this).width() == 12345) ? 'none-defined' : $(this).width();
var height = ($(this).height() == 12345) ? 'none-defined' : $(this).height();
$(this).removeClass("default_width_check");
.default_width_check {
width: 12345;
}
I have a workaround idea that might work.
Define a class named default_width before all other style sheets:
.default_width { width: 1787px }
/* An arbitrary value unlikely to be an image's width, but not too large
in case the browser reserves memory for it */
to find out whether an image has a width set:
Clone it in jQuery: element = $("#img").clone()
give the cloned element the default_width class: element.addClass("default_width")
If its width is 1787px, it has no width set - or, of course, is natively 1787px wide, which is the only case in which this method will not work.
I'm not entirely sure whether this will work, but it might. Edit: As #bobince points out in the comments, you will need to insert the element into the DOM for all classes to be applied correctly, in order to make a correct width calculation.
No, the getComputedStyle() method on which jQuery's css() function depends cannot distinguish between an width computed from auto vs explicit widths. You can't tell if there was something set in the stylesheet, only from direct inline style="width: ..." (which is reflected in the element's .style.width property).
currentStyle works differently and will give you auto, however this is a non-standard IE extension.
If you really wanted to work it out, you could iterate over document.styleSheets, reading each of their declarations, getting the selector out and querying it to see whether your target element matched, then seeing if it contains a width rule. This would, however, be slow and not at all fun, especially as IE's styleSheet DOM differs from the other browsers. (And it still wouldn't cope with pseudo-elements and pseudo-classes, like :hover.)
You can use image.style.width (image should be your element). This returns an empty string if it's not defined in CSS.
You can check the element's style.cssText if the width is defined;
<img id="pic" style="width:20px;" src="http://sstatic.net/ads/img/careers-ad-header-so.png" />
var pic = document.getElementById('pic');
alert(pic.style.cssText);
But please note of the following styles
border-width: 10px;
width: 10px;
you should only match the width not the border-width.
Consider de following markup:
<div id="outerElement">
<div id="innerElement" style="border: 1px solid blue; background-color: #f0f3f5; margin-top: 100px">
TESTE
</div>
</div>
I want to get the actual final height of outerElement using javascript. I noticed that if I remove the vertical margins from innerElement I am able to get what I want but I cannot alter styles from within the outerElement.
How do I do this?
Obs:
I already tried height, scrollheight and offsetHeight in all browsers. Chrome gives me the expected value (including inner element's margins) for scrollHeight. All other browsers fail.
I'd use jQuery. Try using
$("#myelementId").height()
And see if that does it.
Add clearfix, use jquery height() and remove the clearfix class again.
That's gonna work. : )
If you can set the outer div to style display : inline-block; then scrollHeight will include the margins of child elements.
It will also work if you set style display : flex; (supported by IE 9+)
you could use jQuery:
$('#outerElement').height(); // gets the height of the div
$('#outerElement').outerHeight(); // gets the height of the div including margins and padding
$('#outerElement').innerHeight(); // gets the height of the div including padding
one of those is bound to work.
Try using clientHeight
var outerElement = document.getElementById("outerElement");
if(outerElement.clientHeight) {
alert("Height is "+outerElement.clientHeight+"px");
}
else { alert("Old browser?"); }
I know what you're thinking... "this won't work!" and alas, it doesn't... but if you do something like add a border to outerElement... even for just a moment...
var outerElement = document.getElementById("outerElement");
outerElement.style.border = "1px solid black";
var height = outerElement.clientHeight;
outerElement.style.border = "none";
alert("Height is "+height+"px");
Not the most beautiful solution but it works, and if you can figure out why it works (I sure as hell don't know :P) you might be closer to a good solution...
Some older browsers may not support it though... you'd have to look into it; I can't list 'em.
ok also not pretty but this is how I do it (disclaimer: I stole this from somewhere once)
var height = elem.clientHeight + getBufferHeight(elem, true);
function getBufferHeight(elem, includeMargins) {
if (!elem.visible()) {
return 0;
}
//do new Number instead of parseFloat to avoid rounding errors
var result = 0;
if (includeMargins) {
result =
new Number(elem.getStyle('marginTop').replace(/[^\d\.]/g, '')).ceil() +
new Number(elem.getStyle('marginBottom').replace(/[^\d\.]/g, '')).ceil();
}
result +=
new Number(elem.getStyle('borderBottomWidth').replace(/[^\d\.]/g, '')).ceil() +
new Number(elem.getStyle('borderTopWidth').replace(/[^\d\.]/g, '')).ceil() +
new Number(elem.getStyle('paddingTop').replace(/[^\d\.]/g, '')).ceil() +
new Number(elem.getStyle('paddingBottom').replace(/[^\d\.]/g, '')).ceil();
return result;
}
This is a tricky question as what do you discern as the "appropriate" height. The height of the content inside including borders, what about padding, or the actual margin use? In general browser act fairly consistent on most things, but quirksmode can clear up what you need. (As a hint, if you need the actual margin used, its gonna hurt).
I guess you should go throw all element properties and the make a sum only in this way you can know the exactly height... but in the case of the height is set it by for example clear:both property I dont think is posible to know the heigth of an Element.
A 3 sec thought could be something like:
var o document.getElementById('id').style;
var total = ((o.height.split("px")[0] == "") ? 0 : o.height.split("px")[0]) +
((o.marginTop.split("px")[0] == "") ? 0 : o.marginTop.split("px")[0]) +
((o.marginBottom.split("px")[0] == "") ? 0 : o.marginBottom.split("px")[0]) +
((o.paddingTop.split("px")[0] == "") ? 0 : o.paddingTop.split("px")[0]) +
((o.borderTop.split("px")[0] == "") ? 0 : o.borderTop.split("px")[0]) +
((o.borderBottom.split("px")[0] == "") ? 0 : o.borderBottom.split("px")[0])
But I guess you must include also the document.getElementById('id').height value if have it.... is thougth but can help..
best =)
WARNING WARNING clientHeight almost works but doesn't include margins :(
Just thought I'd add that I've been trying this today, and while nahumsilva & plodder almost have it right (nahumsilva's version appears to be more cross-browser {plodder's doesn't appear to work in Chrome/WebKit, but I'm no expert on these things}), they've both missed that an element may have computed style elements that aren't defined by it's own style.
This was driving me nuts - I was wondering where my <p> elements were getting an extra 16px of margin height - until I realised it was coming from the computed style.
So, long story short, an approach like nahumsilva / plodder worked for me, with the added proviso that you should get the element's computed style with window.getComputedStyle( element, null ), which returns a CSSStyleDeclaration object (like element.style). element.offsetHeight / element.clientHeight should give you the height without margins, so the whole thing looks like:
var cstyle = window.getComputedStyle( element, null );
var elementHeight = element.offsetHeight +
Number( cstyle.marginBottom.replace(/[^\d\.]/g, '') ) +
Number( cstyle.marginTop.replace(/[^\d\.]/g, '') );
try $("#myelementId").outerHeight( true )
This answer may be a little obvious, but if you already know the margin, why not just manually add it to the height?
I have to write a javascript function that is returning the current size (in px) of a div. Unfortunately the div has its weight specified in % instead of px.
The style of the div: position: absolute; width: 100%; height: 100%;
And my width returning function:
function getTableWidth(tableId){
var tabWidth = document.getElementById('pt1::tabb').children[0].children[0].style.width;
return tabWidth;
}
tabWidth is '100%'.
Is it possible to return the px width instead of the % width ?
NOTE: I don't have access to any html/css , as the page I am working on is generated through a complex framework. I can only embed javascript.
Each browser is different. In most you can use the clientWidth and clientHeight properties of the DOM element. In non-IE browsers you can use document.defaultView.getComputedStyle(). However I'd recommend using a framework that takes care of cross-browser issues for you. In jQuery, you can get the current width in pixels using something as simple as $(element).width().
node.offsetWidth
should do the trick (in all browsers!)