Installations
npm install react-cool-dimensions
Developer Guide
Typescript
Yes
Module System
CommonJS
Node Version
16.19.0
NPM Version
8.19.3
Releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (73.76%)
HTML (10.25%)
JavaScript (8.02%)
SCSS (7.53%)
Shell (0.44%)
Love this project? Help keep it running — sponsor us today! 🚀
Developer
Download Statistics
Total Downloads
8,945,977
Last Day
11,281
Last Week
60,185
Last Month
253,105
Last Year
3,164,466
GitHub Statistics
MIT License
938 Stars
1,093 Commits
20 Forks
3 Watchers
23 Branches
5 Contributors
Updated on Feb 11, 2025
Bundle Size
2.73 kB
Minified
1.18 kB
Minified + Gzipped
Package Meta Information
Latest Version
3.0.1
Package Id
react-cool-dimensions@3.0.1
Unpacked Size
52.06 kB
Size
13.83 kB
File Count
8
NPM Version
8.19.3
Node Version
16.19.0
Published on
Mar 08, 2023
Total Downloads
Cumulative downloads
Total Downloads
8,945,977
Last Day
-5.7%
11,281
Compared to previous day
Last Week
1.9%
60,185
Compared to previous week
Last Month
67.9%
253,105
Compared to previous month
Last Year
21.2%
3,164,466
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Peer Dependencies
1
Dev Dependencies
30
REACT COOL DIMENSIONS
A React hook that measure an element's size and handle responsive components with highly-performant way, using ResizeObserver. Try it you will 👍🏻 it!
❤️ it? ⭐️ it on GitHub or Tweet about it.
⚡️ Try yourself: https://react-cool-dimensions.netlify.app
Features
- 🚀 Measures element's size with highly-performant way, using ResizeObserver.
- 🎣 Easy to use, based on React hook.
- 🍰 Easy to handle responsive components, provides an alternative solution to the container queries problem.
- 📦 Supports border-box size measurement.
- 🕹 Supports conditionally updating state.
- 🎛 Super flexible API design to cover most cases for you.
- 📜 Supports TypeScript type definition.
- 🗄️ Server-side rendering compatibility.
- 🦔 Tiny size (~ 1kB gzipped). No external dependencies, aside for the
react
.
Requirement
To use react-cool-dimensions
, you must use react@16.8.0
or greater which includes hooks.
Installation
This package is distributed via npm.
1$ yarn add react-cool-dimensions 2# or 3$ npm install --save react-cool-dimensions
Usage
react-cool-dimensions
has a flexible API design, it can cover simple to complex use cases for you. Here are some examples to show you how does it work.
⚠️ Most modern browsers support ResizeObserver natively. You can also use polyfill for full browser support.
Basic Use Case
To report the size of an element by the width
and height
states.
1import useDimensions from "react-cool-dimensions"; 2 3const App = () => { 4 const { observe, unobserve, width, height, entry } = useDimensions({ 5 onResize: ({ observe, unobserve, width, height, entry }) => { 6 // Triggered whenever the size of the target is changed... 7 8 unobserve(); // To stop observing the current target element 9 observe(); // To re-start observing the current target element 10 }, 11 }); 12 13 return ( 14 <div ref={observe}> 15 Hi! My width is {width}px and height is {height}px 16 </div> 17 ); 18};
💡 You don't have to call
unobserve
when the component is unmounted, this hook will handle it for you.
Responsive Components
We have media queries but those are based on the browser viewport not individual elements. In some cases, we'd like to style components based on the width of a containing element rather than the browser viewport. To meet this demand there's a proposal for container queries, but it still doesn't exist today...
No worries, react-cool-dimensions
provides an alternative solution for us! We can activate the responsive mode by the breakpoints
option. It's a width-based solution, once it's activated we can easily apply different styles to a component according to the currentBreakpoint
state. The overall concept as below.
If you wish to update the state on the breakpoints changed, you can set the updateOnBreakpointChange
option to true
.
1import useDimensions from "react-cool-dimensions"; 2 3const Card = () => { 4 const { observe, currentBreakpoint } = useDimensions({ 5 // The "currentBreakpoint" will be the object key based on the target's width 6 // for instance, 0px - 319px (currentBreakpoint = XS), 320px - 479px (currentBreakpoint = SM) and so on 7 breakpoints: { XS: 0, SM: 320, MD: 480, LG: 640 }, 8 // Will only update the state on breakpoint changed, default is false 9 updateOnBreakpointChange: true, 10 onResize: ({ currentBreakpoint }) => { 11 // Now the event callback will be triggered when breakpoint is changed 12 // we can also access the "currentBreakpoint" here 13 }, 14 }); 15 16 return ( 17 <div class={`card ${currentBreakpoint}`} ref={observe}> 18 <div class="card-header">I'm 😎</div> 19 <div class="card-body">I'm 👕</div> 20 <div class="card-footer">I'm 👟</div> 21 </div> 22 ); 23};
Note: If the
breakpoints
option isn't set or there's no the defined breakpoint (object key) for a range of width. ThecurrentBreakpoint
will be empty string.
Conditionally Updating State
You can use the shouldUpdate
option to conditionally update the state to reduce unnecessary re-renders as below.
1const returnObj = useDimensions({ 2 shouldUpdate: ({ currentBreakpoint, width, height, entry }) => { 3 // Will only update the state when the target element's width greater than 300px 4 return state.width > 300; 5 }, 6});
Note: When
updateOnBreakpointChange
andshouldUpdate
are used at the same time,shouldUpdate
has a higher priority.
Border-box Size Measurement
By default, the hook reports the width
and height
based on the content rectangle of the target element. We can include the padding and border for measuring by the useBorderBoxSize
option. Please note, the width
and height
states are rely on the ResizeObserverEntry.borderBoxSize but it hasn't widely implemented by browsers therefore we need to use polyfill for this feature.
1import useDimensions from "react-cool-dimensions";
2import { ResizeObserver } from "@juggle/resize-observer";
3
4const App = () => {
5 const { observe, width, height } = useDimensions({
6 useBorderBoxSize: true, // Tell the hook to measure based on the border-box size, default is false
7 polyfill: ResizeObserver, // Use polyfill to make this feature works on more browsers
8 });
9
10 return (
11 <div
12 style={{
13 width: "100px",
14 height: "100px",
15 padding: "10px",
16 border: "5px solid grey",
17 }}
18 ref={observe}
19 >
20 {/* Now the width and height will be: 100px + 10px + 5px = 115px */}
21 Hi! My width is {width}px and height is {height}px
22 </div>
23 );
24};
How to Share A ref
?
You can share a ref
as follows:
1import { useRef } from "react"; 2import useDimensions from "react-cool-dimensions"; 3 4const App = () => { 5 const ref = useRef(); 6 const { observe } = useDimensions(); 7 8 return ( 9 <div 10 ref={(el) => { 11 observe(el); // Set the target element for measuring 12 ref.current = el; // Share the element for other purposes 13 }} 14 /> 15 ); 16};
Performance Optimization
The onResize
event will be triggered whenever the size of the target element is changed. We can reduce the frequency of the event callback by activating the responsive mode or implementing our own throttled/debounced function as below. Note that in order to throttle/debounce the function correctly, it will need to be memorized else it will be recreated on every render call.
1import { useMemo } from "react"; 2import _ from "lodash"; 3 4const returnObj = useDimensions({ 5 onResize: useMemo( 6 () => 7 _.throttle(() => { 8 // Triggered once per every 500 milliseconds 9 }, 500), 10 [] 11 ), 12});
Working in TypeScript
This hook supports TypeScript, you can tell the hook what type of element you are going to observe through the generic type:
1const App = () => { 2 const { observe } = useDimensions<HTMLDivElement>(); 3 4 return <div ref={observe} />; 5};
💡 For more available types, please check it out.
API
1const returnObj = useDimensions(options?: object);
Return object
It's returned with the following properties.
Key | Type | Default | Description |
---|---|---|---|
observe | function | To set a target element for measuring or re-start observing the current target element. | |
unobserve | function | To stop observing the current target element. | |
width | number or null | null | The width of the target element in pixel. Null while target has not mounted. |
height | number or null | null | The height of the target element in pixel. Null while target has not mounted.Z |
currentBreakpoint | string | Indicates the current breakpoint of the responsive components. | |
entry | object | The ResizeObserverEntry of the target element. |
Parameter
The options
provides the following configurations and event callback for you.
Key | Type | Default | Description |
---|---|---|---|
breakpoints | object | Activates the responsive mode for responsive components or performance optimization. | |
updateOnBreakpointChange | boolean | false | Tells the hook to update the state on breakpoint changed. |
useBorderBoxSize | boolean | false | Tells the hook to measure the target element based on the border-box size. |
shouldUpdate | function | Tells the hook to conditionally update the state. | |
onResize | function | It's invoked whenever the size of the target element is changed. But in responsive mode, it's invoked based on the changing of the breakpoint rather than the size. | |
polyfill | ResizeObserver | It's used for injecting a polyfill. |
ResizeObserver Polyfill
ResizeObserver has good support amongst browsers, but it's not universal. You'll need to use polyfill for browsers that don't support it. Polyfills is something you should do consciously at the application level. Therefore react-cool-dimensions
doesn't include it.
We recommend using @juggle/resize-observer:
1$ yarn add @juggle/resize-observer 2# or 3$ npm install --save @juggle/resize-observer
Then inject it by the polyfill
option:
1import { ResizeObserver } from "@juggle/resize-observer"; 2 3const { width, height } = useDimensions(ref, { polyfill: ResizeObserver });
Or pollute the window
object:
1import { ResizeObserver, ResizeObserverEntry } from "@juggle/resize-observer"; 2 3if (!("ResizeObserver" in window)) { 4 window.ResizeObserver = ResizeObserver; 5 // Only use it when you have this trouble: https://github.com/wellyshen/react-cool-dimensions/issues/45 6 // window.ResizeObserverEntry = ResizeObserverEntry; 7}
You could use dynamic imports to only load the file when the polyfill is required:
1(async () => { 2 if (!("ResizeObserver" in window)) { 3 const module = await import("@juggle/resize-observer"); 4 window.ResizeObserver = module.ResizeObserver; 5 // Only use it when you have this trouble: https://github.com/wellyshen/react-cool-dimensions/issues/45 6 // window.ResizeObserverEntry = module.ResizeObserverEntry; 7 } 8})();
Articles / Blog Posts
💡 If you have written any blog post or article about
react-cool-dimensions
, please open a PR to add it here.
- Featured on React Status #191.
Contributors ✨
Thanks goes to these wonderful people (emoji key):
Welly 💻 📖 🚧 | Runar Kristoffersen 📖 💻 🤔 | Ricardo Amaral 💻 | Cornelius 🐛 | Joseph Horton 📖 | sirkrisp 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!

No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
SAST tool detected but not run on all commits
Details
- Info: SAST configuration detected: CodeQL
- Warn: 0 commits out of 15 are checked with a SAST tool
Reason
security policy file detected
Details
- Info: security policy file detected: SECURITY.md:1
- Warn: no linked content found
- Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1
- Info: Found text in security policy: SECURITY.md:1
Reason
Found 2/18 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:30
- Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:31
- Warn: no topLevel permission defined: .github/workflows/ci.yml:1
- Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1
- Warn: no topLevel permission defined: .github/workflows/size.yml:1
- Info: no jobLevel write permissions found
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/ci.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/ci.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/ci.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/ci.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:58: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/ci.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/ci.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/ci.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/codeql-analysis.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/codeql-analysis.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/codeql-analysis.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/codeql-analysis.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/size.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/size.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/size.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/wellyshen/react-cool-dimensions/size.yml/master?enable=pin
- Info: 0 out of 10 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 3 third-party GitHubAction dependencies pinned
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
44 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-ghr5-ch3p-vcr6
- Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc
- Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx
- Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc
- Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp
- Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq
- Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488
- Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55
- Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr
- Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j
- Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w
- Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg
- Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p
- Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
- Warn: Project is vulnerable to: GHSA-hc6q-2mpp-qw7j
- Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986
- Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6
- Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7
- Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw
- Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq
- Warn: Project is vulnerable to: GHSA-434g-2637-qmqr
- Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m
- Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw
- Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p
- Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747
- Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-g4rg-993r-mgx7
- Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v
Score
3.3
/10
Last Scanned on 2025-02-03
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More