Is there an easy cross-browser way to get computed style of an element in PrototypeJS, without checking document.defaultView... and other properties? ...so that the code looked like
var elt = $$('.xyz')[k],
border = elt.getComputedStyle('border-bottom-width')
PrototypeJs provides getDimensions, -Width, and -Height methods that return computed dimensions, but there's no way to get other computed styles, like borders, backgrounds, etc.
I've found several stand-alone implementations of getComputedStyle, but maybe there's a patch/plugin for PrototypeJS that does that?
Prototype's getStyle method encapsulates most of the cross-browser computed style work you're looking for:
var bgColor = $(element).getStyle('background-color');
From the docs:
This method looks up the CSS property
of an element whether it was applied
inline or in a stylesheet. It works
around browser inconsistencies
regarding float, opacity, which
returns a value between 0 (fully
transparent) and 1 (fully opaque),
position properties (left, top, right
and bottom) and when getting the
dimensions (width or height) of hidden
elements.
However, this method will not return styles applied in a stylesheet in Internet Explorer <= 8, because it uses the getComputedStyle() method, which is the incorrect method for versions 8 and lower: http://www.quirksmode.org/dom/w3c_css.html
Not that I know of.
This is probably because the "get computed style" implementations are so different that it's hardly possible to guarantee uniform results (Which renders them useless for a cross-browser framework).
For example, getting the computed font size cross-browser is not always possible, as I learned in this question.
Related
This question already has answers here:
Get element CSS property (width/height) value as it was set (in percent/em/px/etc)
(5 answers)
Closed 3 years ago.
I'm trying to parse a web page (any web page actually) and dynamically apply some adjustments to font sizes of DOM elements.
As far as I could see:
element.style.fontSize will return the value plus unit, e.g.: "11px", or "1em", or "1rem", which is fine for me, BUT...
element.style.fontSize will return no value if the font size is defined via a css class. So if I want to address all DOM elements (most of which won't have their font-size defined in their style attribute), I'll have to use getComputedStyle instead, BUT...
getComputedStyle seems to return all font sizes in px, even if it was originally defined in em or rem in the css, e.g.: font size defined as "1rem" => getComputedStyle returns "16px" instead.
For my purpose, I'd like to know the original font-size value with its original unit, so get "1rem" rather than "16px".
Is it possible?
If you're trying to dynamically adjust font sizes, then .style.fontSize is the way to go. This is due to the fact that inline styles have a much higher level of specificity, so your changes will override any styles that may be present in the stylesheet.
.getComputedStyle() returns the CSS value after "after applying active stylesheets and resolving any basic computation those values may contain". That means that the rem is taken into account and adjusted accordingly. Having said this, if you need to target based on existing values set in the stylesheet, I think .getComputedStyle() is the best bet. The fact that it shows the calculated value shouldn't make a difference; you're still able to manipulate 'changes' after the conversion -- and you can even convert back if need be.
Either way, you'll need to set the property with .style.fontSize.
If I'm already using jQuery in my app, but want to improve performance as much as I can. Does it improve performance any to use vanilla JS instead of jQuery (for example) for getting window width in some places of my code?
There is actually a huge performance difference! I tried it out in jsPerf: https://jsperf.com/window-width-jquery-vs-vanilla/1
Vanilla trumps jQuery!
There is of course notable overhead when you have to instantiate a new jQuery object ($(window)). If you must use jQuery, save the window jQuery object to a variable.
There is always a performance price for using JQuery instead of plain (vanilla) JavaScript, since it is a library built on top of JavaScript to address browser native DOM API inconsistencies and make iteration over elements simpler (to name a few things).
Some examples of when to use JQuery:
Tedious cross browser situations (for example AJAX)
To facilitate chaining, simplify working on groups of elements together.
An exapmle of when not to use JQuery:
When executing a loop many times.
Unwrap all tags of a certain type. JQuery is simple but doesn't perform well when there are MANY elements to iterate over:
$('span').unwrap(); // unwrap all span elements
The native DOM API will perform better:
var spans = document.getElementsByTagName('span');
while( spans[0] ) {
var parent = spans[0].parentNode;
while( spans[0].firstChild ) {
parent.insertBefore( spans[0].firstChild, spans[0]);
}
parent.removeChild( spans[0] );
}
window.innerWidth: with scrollbar
$(window).innerWidth(): wrong usage
$(window).width(): without scrollbar
mediaquery: with scrollbar (at least the standard ones)
$(window).innerWidth(): this is actually a wrong way to get the inner
width of window, because api.jquery.com/innerWidth states that “This
method is not applicable to window and document objects; for these,
use .width() instead.”
But what if we just need the inner width of window? We might need to
adjust images according to width. In this case, use window.innerWidth.
window.innerWidth: quite literally, the width of window WITH scroll
bar (as all mediaquery should behave). But sadly, IE8 doesn’t support
it.
So use:
var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
To be clear, window.innerWidth is different from the latter two since
only window.innerWidth includes scrollbar. But we don’t need to worry
about getting the wrong width in IE8 because it doesn’t support
Mediaquery–if it wants the width, it’ll have to resort to javascript
solutions anyway.
Source: http://luxiyalu.com/window-innerwidth-vs-window-innerwidth/
The MDN documentation for getComputedStyle states
The values returned by getComputedStyle are known as resolved values.
These are usually the same as the CSS 2.1 computed values, but for
some older properties like width, height or padding, they are instead
the used values.
Is there a way to only get the computed values without the used ones?
My use case is this:
Take for instance a body element. The browsers width is currently 600px. If you call getComputedStyle on the body element, the style returned would contain width: 600px.
Resize the browser and the width will be different again, although the "correct" value should probably be auto.
I'd need the returned style to be idempotent, meaning that I can set the style back on the element without changing some values (like width) to fixed values.
For a given element and style property you would need the first of:
A value that has been explicitly applied to an element (through the style attribute or CSS)
The browser's default value for that property
You cannot do that reliably because the CSS spec does not provide a way to access the browser's default CSS rules.
This question already has answers here:
How to get computed style of a HTMLElement
(2 answers)
Closed 9 years ago.
As far as I was aware CSS properties of the DOM element style are camel-cased, such that min-height would be element.style.minHeight, but in my example below the style property is empty, but jQuery's abstraction gets it correctly.
// element with css: #test{ min-height: 100px; }
var el = document.getElementById('test');
console.log( el.style.minHeight );
// ""
console.log( $(el).css('min-height') );
// "100px"
See fiddle for this in action.
What is jQuery doing to pull the correct style property that I'm not doing?
interestingly enough, adding a style attribute directly on the html element does work.
You can use window.getComputedStyle(el,null).getPropertyValue("min-height") and see if it returns the right value.
WARNING: It might not work on IE < 8.
From Mozilla's website...
CSS 2.0 defined only computed value as the last step in a property's calculation. Then, CSS 2.1 introduced the distinct definition of used value so that an element could explicitly inherit a width/height of a parent whose computed value is a percentage. For CSS properties that don't depend on layout (e.g. display, font-size, line-height), the computed values and used values are the same. These are the properties that do depend on layout so have a different computed value and used value: (taken from CSS 2.1 Changes: Specified, computed, and actual values):
background-position
bottom, left, right, top
height, width
margin-bottom, margin-left, margin-right, margin-top,
min-height, min-width
padding-bottom, padding-left, padding-right, padding-top
text-indent
Try this:
style = window.getComputedStyle(el),
console.log( style.getPropertyValue('min-height'));
Check an update of your fiddle:
http://jsfiddle.net/VEuJe/4/
JQuery method css is not so simple. You can check on this link jquery css
The .css() method is a convenient way to get a style property from the
first matched element, especially in light of the different ways
browsers access most of those properties (the getComputedStyle()
method in standards-based browsers versus the currentStyle and
runtimeStyle properties in Internet Explorer) and the different terms
browsers use for certain properties. For example, Internet Explorer's
DOM implementation refers to the float property as styleFloat, while
W3C standards-compliant browsers refer to it as cssFloat. For
consistency, you can simply use "float", and jQuery will translate it
to the correct value for each browser.
edit:
The problem seems to be that the font size isnt explicitly set and is set by the css class only. so style.fontSize always returns an empty string
if there another way to return the font size?
var allMainFrameElems = parent.main.document.getElementsByTagName('*');
for (i=0; i < allMainFrameElems.length; i++){
if(allMainFrameElems[i].style.fontSize != null){
alert(llMainFrameElems[i].style.fontSize);
}
}
If the fontSize style in not explicitly set on an element (e.g. <p style="font-size:12pt;">...</p>), you won't be able to get it from anywhere. Font-sizes are most often set in your CSS classes, which are not reachable from your element's properties, and the elements do not have any font-size related properties.
In order to even come close to doing this you will need to do some tricks and will not be able to definatively determine font size. Basically you will have to manipulate the page a great deal on every element (not good) just to determine this.
See this fiddle page, especially the pixelPerEm function I tossed together very quickly. http://jsfiddle.net/MarkSchultheiss/vc8Zy/
It is not very clean at the moment and IF I get time I might try to make it better but it might give you something to start with even if it is NOT very pretty.
EDIT: basic explanation is to utilize the em css, inject an element with a known setting, calculate the pixel offset on the injection and then remove the injected element. None of that is pretty and all of it is error/bug prone or has potential for issues.