├── .nvmrc ├── .gitignore ├── tasks └── version.js ├── bower.json ├── README.md ├── LICENSE.md ├── package.json ├── test ├── index.html ├── tests.css └── tests.js ├── sandbox.html └── get-size.js /.nvmrc: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components/ 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /tasks/version.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const { version } = require('../package.json'); 6 | 7 | function dir( file ) { 8 | return path.resolve( __dirname, file ); 9 | } 10 | 11 | let content = fs.readFileSync( dir('../get-size.js'), 'utf8' ); 12 | content = content.replace( /getSize v[\w.-]+/, 13 | `getSize v${version}` ); 14 | fs.writeFileSync( dir('../get-size.js'), content, 'utf8' ); 15 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get-size", 3 | "description": "measures element size", 4 | "main": "get-size.js", 5 | "authors": [ 6 | "David DeSandro" 7 | ], 8 | "license": "MIT", 9 | "keywords": [ 10 | "size", 11 | "DOM" 12 | ], 13 | "homepage": "https://github.com/desandro/get-size", 14 | "ignore": [ 15 | "**/.*", 16 | "package.json", 17 | "node_modules", 18 | "bower_components", 19 | "test", 20 | "tests", 21 | "sandbox.html" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # getSize 2 | 3 | Get the size of elements. Used in [Masonry](https://masonry.desandro.com), [Isotope](https://isotope.metafizzy.co), & [Flickity](https://flickity.metafizzy.co). 4 | 5 | ``` js 6 | var size = getSize( elem ); 7 | // elem can be an element 8 | var size = getSize( document.querySelector('.selector') ) 9 | // elem can be a selector string 10 | var size = getSize('.selector') 11 | ``` 12 | 13 | Returns an object with: 14 | 15 | + width, height 16 | + innerWidth, innerHeight 17 | + outerWidth, outerHeight 18 | + paddingLeft, paddingTop, paddingRight, paddingBottom 19 | + marginLeft, marginTop, marginRight, marginBottom 20 | + borderLeftWidth, borderTopWidth, borderRightWidth, borderBottomWidth 21 | + isBorderBox 22 | 23 | Browser support: Chrome 51+, Firefox 50+, Edge 12+, Safari 10+, 24 | 25 | ## Install 26 | 27 | npm: `npm install get-size` 28 | 29 | Yarn: `yarn add get-size` 30 | 31 | ## MIT License 32 | 33 | getSize is released under the MIT License. Have at it. 34 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2021 [David DeSandro](https://desandro.com) and [contributors](https://github.com/desandro/get-size/graphs/contributors) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get-size", 3 | "version": "3.0.0", 4 | "description": "measures element size", 5 | "main": "get-size.js", 6 | "devDependencies": { 7 | "eslint": "^7.32.0", 8 | "eslint-plugin-metafizzy": "^1.2.1", 9 | "qunit": "^2.17.2" 10 | }, 11 | "directories": { 12 | "test": "test" 13 | }, 14 | "scripts": { 15 | "lint": "npx eslint .", 16 | "test": "echo \"View test/ in browser\" && exit 1", 17 | "version": "node tasks/version.js && git add -A ." 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/desandro/get-size.git" 22 | }, 23 | "keywords": [ 24 | "size", 25 | "DOM" 26 | ], 27 | "author": "David DeSandro", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/desandro/get-size/issues" 31 | }, 32 | "homepage": "https://github.com/desandro/get-size", 33 | "eslintConfig": { 34 | "plugins": [ 35 | "metafizzy" 36 | ], 37 | "extends": "plugin:metafizzy/browser", 38 | "env": { 39 | "browser": true, 40 | "commonjs": true 41 | }, 42 | "parserOptions": { 43 | "ecmaVersion": 2018 44 | }, 45 | "rules": { 46 | "complexity": [ 47 | "error", 48 | 20 49 | ] 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Get Size Tests 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |

Get Size Tests

20 | 21 |
22 |
23 |
24 | 25 |
26 |
27 |
28 | 29 |
30 |
31 |
32 | 33 |
34 |
35 |
36 | 37 |
38 |
39 |
40 | 41 |
42 |
43 |
44 | 45 |
46 |
47 |
48 | 49 |
50 |
51 |
52 | 53 |
54 |
55 |
56 | 57 |
58 |
59 |
60 |
61 | 62 |
63 |
64 |
65 | 66 |
67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /test/tests.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | width: 400px; 4 | padding: 20px; 5 | } 6 | 7 | .container { 8 | width: 400px; 9 | height: 200px; 10 | background: #333; 11 | margin-bottom: 20px; 12 | } 13 | 14 | .box { 15 | background: #0AE; 16 | color: #F90; 17 | border-color: #F90; 18 | } 19 | 20 | /* align to right side */ 21 | #qunit { 22 | position: absolute; 23 | left: 0; 24 | top: 20px; 25 | margin-left: 440px; 26 | margin-right: 10px; 27 | } 28 | 29 | 30 | /* Boxes 31 | ------------------------- */ 32 | 33 | #ex2 .box { 34 | height: 100%; 35 | } 36 | 37 | #ex3 .box { 38 | width: 50%; 39 | height: 50%; 40 | } 41 | 42 | #ex4 .box, 43 | #ex5 .box { 44 | width: 200px; 45 | height: 100px; 46 | border: 10px solid; 47 | } 48 | 49 | 50 | #ex5 .box { 51 | margin: 10px 20px 30px 40px; 52 | } 53 | 54 | #ex6 .box { 55 | width: 200px; 56 | height: 100px; 57 | padding: 10px 20px 30px 40px; 58 | } 59 | 60 | #ex7 .box { 61 | height: 100px; 62 | padding: 10px 20px 30px 40px; 63 | } 64 | 65 | #ex8 .box { 66 | position: relative; 67 | width: 66.6666%; 68 | height: 66.666%; 69 | } 70 | 71 | /* border box */ 72 | #ex9 .box { 73 | -webkit-box-sizing: border-box; 74 | -moz-box-sizing: border-box; 75 | box-sizing: border-box; 76 | height: 100%; 77 | border-style: solid; 78 | border-width: 10px 20px 30px 40px; 79 | padding: 10px 20px 30px 40px; 80 | } 81 | 82 | #hidden .box { 83 | display: none; 84 | width: 200px; 85 | height: 100px; 86 | padding: 10px 20px 30px 40px; 87 | margin: 10px 20px 30px 40px; 88 | } 89 | 90 | #percent .box { 91 | width: 200px; 92 | height: 100px; 93 | margin-top: 20%; 94 | margin-left: 10%; 95 | } 96 | -------------------------------------------------------------------------------- /sandbox.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | getSize 7 | 8 | 52 | 53 | 54 | 55 | 56 |

getSize

57 | 58 |
59 |
box1
60 |
61 | 62 |
63 |
box2
64 |
65 | 66 |
67 |
box3
68 |
69 | 70 |
71 |
box4
72 |
73 | 74 |
75 |
box5
76 |
77 | 78 |
79 |
box6
80 |
81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /get-size.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * getSize v3.0.0 3 | * measure size of elements 4 | * MIT license 5 | */ 6 | 7 | ( function( window, factory ) { 8 | if ( typeof module == 'object' && module.exports ) { 9 | // CommonJS 10 | module.exports = factory(); 11 | } else { 12 | // browser global 13 | window.getSize = factory(); 14 | } 15 | 16 | } )( window, function factory() { 17 | 18 | // -------------------------- helpers -------------------------- // 19 | 20 | // get a number from a string, not a percentage 21 | function getStyleSize( value ) { 22 | let num = parseFloat( value ); 23 | // not a percent like '100%', and a number 24 | let isValid = value.indexOf('%') == -1 && !isNaN( num ); 25 | return isValid && num; 26 | } 27 | 28 | // -------------------------- measurements -------------------------- // 29 | 30 | let measurements = [ 31 | 'paddingLeft', 32 | 'paddingRight', 33 | 'paddingTop', 34 | 'paddingBottom', 35 | 'marginLeft', 36 | 'marginRight', 37 | 'marginTop', 38 | 'marginBottom', 39 | 'borderLeftWidth', 40 | 'borderRightWidth', 41 | 'borderTopWidth', 42 | 'borderBottomWidth', 43 | ]; 44 | 45 | let measurementsLength = measurements.length; 46 | 47 | function getZeroSize() { 48 | let size = { 49 | width: 0, 50 | height: 0, 51 | innerWidth: 0, 52 | innerHeight: 0, 53 | outerWidth: 0, 54 | outerHeight: 0, 55 | }; 56 | measurements.forEach( ( measurement ) => { 57 | size[ measurement ] = 0; 58 | } ); 59 | return size; 60 | } 61 | 62 | // -------------------------- getSize -------------------------- // 63 | 64 | function getSize( elem ) { 65 | // use querySeletor if elem is string 66 | if ( typeof elem == 'string' ) elem = document.querySelector( elem ); 67 | 68 | // do not proceed on non-objects 69 | let isElement = elem && typeof elem == 'object' && elem.nodeType; 70 | if ( !isElement ) return; 71 | 72 | let style = getComputedStyle( elem ); 73 | 74 | // if hidden, everything is 0 75 | if ( style.display == 'none' ) return getZeroSize(); 76 | 77 | let size = {}; 78 | size.width = elem.offsetWidth; 79 | size.height = elem.offsetHeight; 80 | 81 | let isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 82 | 83 | // get all measurements 84 | measurements.forEach( ( measurement ) => { 85 | let value = style[ measurement ]; 86 | let num = parseFloat( value ); 87 | // any 'auto', 'medium' value will be 0 88 | size[ measurement ] = !isNaN( num ) ? num : 0; 89 | } ); 90 | 91 | let paddingWidth = size.paddingLeft + size.paddingRight; 92 | let paddingHeight = size.paddingTop + size.paddingBottom; 93 | let marginWidth = size.marginLeft + size.marginRight; 94 | let marginHeight = size.marginTop + size.marginBottom; 95 | let borderWidth = size.borderLeftWidth + size.borderRightWidth; 96 | let borderHeight = size.borderTopWidth + size.borderBottomWidth; 97 | 98 | // overwrite width and height if we can get it from style 99 | let styleWidth = getStyleSize( style.width ); 100 | if ( styleWidth !== false ) { 101 | size.width = styleWidth + 102 | // add padding and border unless it's already including it 103 | ( isBorderBox ? 0 : paddingWidth + borderWidth ); 104 | } 105 | 106 | let styleHeight = getStyleSize( style.height ); 107 | if ( styleHeight !== false ) { 108 | size.height = styleHeight + 109 | // add padding and border unless it's already including it 110 | ( isBorderBox ? 0 : paddingHeight + borderHeight ); 111 | } 112 | 113 | size.innerWidth = size.width - ( paddingWidth + borderWidth ); 114 | size.innerHeight = size.height - ( paddingHeight + borderHeight ); 115 | 116 | size.outerWidth = size.width + marginWidth; 117 | size.outerHeight = size.height + marginHeight; 118 | 119 | return size; 120 | } 121 | 122 | return getSize; 123 | 124 | } ); 125 | -------------------------------------------------------------------------------- /test/tests.js: -------------------------------------------------------------------------------- 1 | /** 2 | * getSize tests 3 | * with QUnit 4 | **/ 5 | 6 | /* globals getSize, QUnit */ 7 | 8 | ( function() { 9 | 10 | function getBoxSize( num ) { 11 | let box = document.querySelector( '#ex' + num + ' .box' ); 12 | return getSize( box ); 13 | } 14 | 15 | QUnit.test( 'arguments', function( assert ) { 16 | assert.ok( !getSize( 0 ), 'Number returns falsey' ); 17 | assert.ok( !getSize( document.querySelector('#foobabbles') ), 18 | 'bad querySelector returns falsey' ); 19 | assert.ok( getSize('#ex1'), 'query selector string works' ); 20 | } ); 21 | 22 | QUnit.test( 'ex1: no styling', function( assert ) { 23 | let size = getBoxSize( 1 ); 24 | assert.equal( size.width, 400, 'Inherit container width' ); 25 | assert.equal( size.height, 0, 'No height' ); 26 | assert.equal( size.isBorderBox, false, 'isBorderBox' ); 27 | } ); 28 | 29 | QUnit.test( 'ex2: height: 100%', function( assert ) { 30 | let size = getBoxSize( 2 ); 31 | assert.equal( size.height, 200, 'Inherit height' ); 32 | } ); 33 | 34 | QUnit.test( 'ex3: width: 50%; height: 50%', function( assert ) { 35 | let size = getBoxSize( 3 ); 36 | assert.equal( size.width, 200, 'half width' ); 37 | assert.equal( size.height, 100, 'half height' ); 38 | } ); 39 | 40 | QUnit.test( 'ex4: border: 10px solid', function( assert ) { 41 | let size = getBoxSize( 4 ); 42 | // console.log( size ); 43 | assert.equal( size.width, 220, 'width = 220 width' ); 44 | assert.equal( size.height, 120, 'height = 120 height' ); 45 | assert.equal( size.innerWidth, 200, 'innerWidth = 200 width' ); 46 | assert.equal( size.innerHeight, 100, 'innerHeight = 200 width' ); 47 | assert.equal( size.outerWidth, 220, 'outerWidth = 200 width + 10 border + 10 border' ); 48 | assert.equal( size.outerHeight, 120, 49 | 'outerHeight = 100 height + 10 border + 10 border' ); 50 | } ); 51 | 52 | QUnit.test( 'ex5: border: 10px solid; margin: 15px', function( assert ) { 53 | // margin: 10px 20px 30px 40px; 54 | let size = getBoxSize( 5 ); 55 | // console.log( size ); 56 | assert.equal( size.width, 220, 'width = 220 width' ); 57 | assert.equal( size.height, 120, 'height = 120 height' ); 58 | assert.equal( size.marginTop, 10, 'marginTop' ); 59 | assert.equal( size.marginRight, 20, 'marginRight' ); 60 | assert.equal( size.marginBottom, 30, 'marginBottom' ); 61 | assert.equal( size.marginLeft, 40, 'marginLeft ' ); 62 | assert.equal( size.innerWidth, 200, 'innerWidth = 200 width' ); 63 | assert.equal( size.innerHeight, 100, 'innerHeight = 200 width' ); 64 | assert.equal( size.outerWidth, 280, 'outerWidth = 200 width + 20 border + 60 margin' ); 65 | assert.equal( size.outerHeight, 160, 66 | 'outerHeight = 100 height + 20 border + 40 margin' ); 67 | } ); 68 | 69 | QUnit.test( 'ex6: padding, set width/height', function( assert ) { 70 | let size = getBoxSize( 6 ); 71 | // console.log( size ); 72 | assert.equal( size.width, 260, 'width' ); 73 | assert.equal( size.height, 140, 'height' ); 74 | assert.equal( size.innerWidth, 200, 75 | 'innerWidth = 200 width - 20 padding - 40 padding' ); 76 | assert.equal( size.innerHeight, 100, 77 | 'innerHeight = 200 height - 10 padding - 30 padding' ); 78 | assert.equal( size.outerWidth, 260, 'outerWidth' ); 79 | assert.equal( size.outerHeight, 140, 'outerHeight' ); 80 | 81 | } ); 82 | 83 | QUnit.test( 'ex7: padding, inherit width', function( assert ) { 84 | // padding: 10px 20px 30px 40px; 85 | let size = getBoxSize( 7 ); 86 | // console.log( size ); 87 | assert.equal( size.width, 400, 'width' ); 88 | assert.equal( size.height, 140, 'height' ); 89 | assert.equal( size.paddingTop, 10, 'paddingTop' ); 90 | assert.equal( size.paddingRight, 20, 'paddingRight' ); 91 | assert.equal( size.paddingBottom, 30, 'paddingBottom' ); 92 | assert.equal( size.paddingLeft, 40, 'paddingLeft ' ); 93 | assert.equal( size.innerWidth, 340, 94 | 'innerWidth = 400 width - 20 padding - 40 padding' ); 95 | assert.equal( size.innerHeight, 100, 96 | 'innerHeight = 200 height - 10 padding - 30 padding' ); 97 | assert.equal( size.outerWidth, 400, 'outerWidth' ); 98 | assert.equal( size.outerHeight, 140, 'outerHeight' ); 99 | 100 | } ); 101 | 102 | QUnit.test( 'ex8: 66.666% values', function( assert ) { 103 | let size = getBoxSize( 8 ); 104 | 105 | if ( size.width % 1 ) { 106 | assert.ok( size.width > 266.6 && size.width < 266.7, 107 | 'width is between 266.6 and 266.7' ); 108 | } else { 109 | // IE8 and Safari 110 | assert.equal( size.width, 267, 'width is 267' ); 111 | } 112 | 113 | if ( size.height % 1 ) { 114 | assert.ok( size.height > 133.3 && size.height < 133.4, 115 | 'height is between 133.3 and 133.4' ); 116 | } else { 117 | // IE8 118 | assert.equal( size.height, 133, 'width is 133' ); 119 | } 120 | } ); 121 | 122 | QUnit.test( 'ex9: border-box', function( assert ) { 123 | let size = getBoxSize( 9 ); 124 | assert.equal( size.isBorderBox, true, 'isBorderBox' ); 125 | assert.equal( size.width, 400, 'width' ); 126 | assert.equal( size.height, 200, 'height' ); 127 | assert.equal( size.innerWidth, 280, 'innerWidth' ); 128 | assert.equal( size.innerHeight, 120, 'innerHeight' ); 129 | assert.equal( size.outerWidth, 400, 'outerWidth' ); 130 | assert.equal( size.outerHeight, 200, 'outerHeight' ); 131 | } ); 132 | 133 | QUnit.test( 'display: none', function( assert ) { 134 | let size = getSize( document.querySelector('#hidden .box1') ); 135 | assert.strictEqual( size.width, 0, 'width' ); 136 | assert.strictEqual( size.height, 0, 'height' ); 137 | assert.strictEqual( size.innerWidth, 0, 'innerWidth' ); 138 | assert.strictEqual( size.innerHeight, 0, 'innerHeight' ); 139 | assert.strictEqual( size.outerWidth, 0, 'outerWidth' ); 140 | assert.strictEqual( size.outerHeight, 0, 'outerHeight' ); 141 | 142 | size.width = 300; 143 | 144 | size = getSize( document.querySelector('#hidden .box2') ); 145 | assert.strictEqual( size.width, 0, 'cannot over write zeroSize' ); 146 | 147 | } ); 148 | 149 | QUnit.test( 'percent values', function( assert ) { 150 | let size = getSize( document.querySelector('#percent .box') ); 151 | assert.strictEqual( size.marginLeft, 40, 'marginLeft' ); 152 | assert.strictEqual( size.marginTop, 80, 'marginTop' ); 153 | assert.strictEqual( size.width, 200, 'width' ); 154 | assert.strictEqual( size.height, 100, 'height' ); 155 | assert.strictEqual( size.innerWidth, 200, 'innerWidth' ); 156 | assert.strictEqual( size.innerHeight, 100, 'innerHeight' ); 157 | assert.strictEqual( size.outerWidth, 240, 'outerWidth' ); 158 | assert.strictEqual( size.outerHeight, 180, 'outerHeight' ); 159 | } ); 160 | 161 | } )( window ); 162 | --------------------------------------------------------------------------------