4

I am using puppeteer to take screengrabs of content in an application I have built. The majority of my code is working but I have a couple of scenarios where the results are not as expected.

I can successfully instruct puppeteer to take a screen grab of an element with a defined css height and width using getBoundingClientRect() on the element but in scenarios where there is not defined height/width.

I was wondering if it was technically possible to get the height and width of an element based on the height and width of the inner elements.

For example (or the most likely case I am going to come across) I may have a piece of content where the body has no style parameters set but the inner content will have a height set. It might not be the first child element but it could even a child of the child element.

I have explored using get getBoundingClientRect() and offsetHeight but have had no success.

Is there a method that would allow me to get the calculated height / width of an element?

var body = document.querySelector('body');

console.log(body.clientHeight);
console.log(body.style.height);
console.log(body.getClientRects());
console.log(body.getBoundingClientRect());
#container {
  height:200px;
  width:200px;
  background-color:blue;
  border:1px solid black;
  color: white;
  text-align: center;
}
<body>
  <div id="container">
    HELLO 
  </div>
</body>
Martin54
  • 1,349
  • 2
  • 13
  • 34
ypoulakas
  • 401
  • 4
  • 7
  • 1
    Does this answer your question? [How do I retrieve an HTML element's actual width and height?](https://stackoverflow.com/questions/294250/how-do-i-retrieve-an-html-elements-actual-width-and-height) – Rob Dec 06 '19 at 15:25
  • Not really, the result on the body element returns 0 for the height and the width of the viewport as the width. – ypoulakas Dec 08 '19 at 19:53

2 Answers2

7

In Puppeteer, this can be done with boundingBox(). Use the page or element selector to get the element, then call elem.boundingBox() to get the x, y, width, and height of the element. See the following code:

const elem = await page.$('.portal-body');
const boundingBox = await elem.boundingBox();
console.log('boundingBox', boundingBox)

For my example, the console logged the following:

2020-12-02 12:58 -08:00: boundingBox { x: 0, y: 0, width: 984, height: 1072 }

That width and height exactly matched the element, as you can see in the lower left of the screenshot: enter image description here

Andrew
  • 2,368
  • 1
  • 23
  • 30
1

On the basis that your <body> element is not modified, this should work fine and should equal the height & width of your body.

var width = document.getElementById('container').offsetWidth;
var height = document.getElementById('container').offsetHeight;

Documentation: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements

awoodhead
  • 87
  • 8
  • Hi Awoodhead, thanks for the suggestion. to explain the scenario further the code I have created won't always contain a div called 'container', I know it will only contain a body element. To explain the code/problem further, I am trying to grab a good thumbnail of a page using puppeteer, so the page I am trying to screen grab wont always be the same structure, its totally out of my control. – ypoulakas Dec 08 '19 at 19:57
  • @ypoulakas Okay I think I understand - Is Jquery available for you to use? You could quite easily grab *all* elements contained within the body, and calculate there forwards opposed to a singular selection such as 'container'. – awoodhead Dec 09 '19 at 10:31
  • Im thinking thats the approach I will have to take. Jquery isn't available as such, I will have to workout if it can be injected into the puppeteer.evaluate function. – ypoulakas Dec 09 '19 at 11:58