2

I know the method .width() from jQuery returns the element's width without padding, border and margin.

In the accepted answer Table with vertical scroll, in which I can't comment, such method is used to get the width of the td elements of the first row of the table.

One of the jsFiddle in the answer there can be used to see the values returned by the method.

I tried to reproduce the behavior with this piece of code:

    let colunas = document.querySelector('.scroll tbody tr:first-child').children;
    let colunasWidth = [];
    for (let i = 0, length = colunas.length; i < length; i++) {
        colunasWidth.push(colunas[i].offsetWidth);//Width/clientWidth
    }

I tried the various widths (offsetWidth, width, clientWidth), none gave the same result as jQuery and then I tried to get the border and padding width to subtract from such various widths, but I can't think of a way to get the math or right properties right.

Is there a simple and straightfoward way to do it?

  • 4
    see this - https://stackoverflow.com/a/9619396/1816407 – MakeLoveNotWar Oct 23 '18 at 21:18
  • 2
    I wonder whether looking at the jQuery source code would help you? (it has certainly helped me when I've had similar sorts of questions in the past) – Spudley Oct 23 '18 at 22:04
  • @MancharyManchaary The mentioned properties in the link you provided are the ones I already tried out. I think the answers by 'sneakybastardd' and 'colxi' are the ones I'm looking for. – Thullyo Castilho Oct 24 '18 at 00:24
  • @Spudley thank you, but the jQuery codebase is quite complex, and I coudn't even find this specific method hahaha – Thullyo Castilho Oct 24 '18 at 00:24

2 Answers2

2

You want window.getComputedStyle and .getPropertyValue What it does is, it gets the styles used and then gets the actual width value of the element.

Here's a jsfiddle to show you: http://jsfiddle.net/u9d27wno/1/

var jquerywidth = $("#container").width();
var jqueryishwidth = window.getComputedStyle(document.getElementById("container"));
var offsetWidth = document.getElementById('container').offsetWidth;
var clientWidth = document.getElementById('container').clientWidth;
var msg = "offsetWidth: " + offsetWidth + "<br>\n";
msg += "clientWidth: " + clientWidth + "<br>\n";
msg += "jQuery width: " + jquerywidth + "<br>\n";
msg += "jQueryish width: " + jqueryishwidth.getPropertyValue("width") + "<br>\n";
document.getElementById('msg').innerHTML = msg;
//alert(document.getElementById('msg').innerHTML);

Let me know if that's the solution you needed!

benvc
  • 14,448
  • 4
  • 33
  • 54
Sneakybastardd
  • 288
  • 1
  • 5
  • 17
  • You are indeed a sneaky bastard. – random_user_name Oct 23 '18 at 22:53
  • Your handle is "Sneakybastardd". Your answer is good. So, you live up to your name: Sneaky Bastard. – random_user_name Oct 23 '18 at 23:03
  • @Sneakybastardd I just tested your answer and it is exactly what I was looking for! Thank you very much! Just to point it out: I tried `jqueryishwidth.width` and it gives the same result as `getPropertyByValue`. The two differences, it seems, to the jQuery way, are: 1- jQuery rounds the numbers, so it loses precision; 2- jQuery gives the value already without the 'px' string, so if only the value is needed, the code examplified by 'colxi' in the other answer solves it: `jqueryishwidth.width.slice(0,-2)` – Thullyo Castilho Oct 24 '18 at 00:58
2

You can use element.clientWidth and getComputedStyle together, to obtain teh value you are looking for...

element.clientWidth

The Element.clientWidth property is zero for elements with no CSS or inline layout boxes, otherwise it's the inner width of an element in pixels. It includes padding but not the vertical scrollbar (if present, if rendered), border or margin.

window.getComputedStyle

The window.getComputedStyle() method returns an object that reports the values of all CSS properties of an element after applying active stylesheets and resolving any basic computation those values may contain.

function width(el){
  // get element computed styles
  let styles=getComputedStyle(el);
  // remove the 'px' from the returned values
  let paddingLeft = styles['padding-left'].slice(0,-2);
  let paddingRight= styles['padding-right'].slice(0,-2);
  // substract paddings from value returned by clientWidth, and return value
  return el.clientWidth - paddingLeft - paddingRight;
}

// test
let w = width(document.getElementById('test'))

console.log( 'VanillaJS:' , w )
console.log( 'JQuery : ', $('#test').width())
#test{
  border:10px solid red;
  width:200px;
  margin:10px;
  padding:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test">
  I'm 200px + <br>
  10px padding + <br>
  10px border +<br>
  10px margin
</div>
colxi
  • 7,640
  • 2
  • 45
  • 43