Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use a callback assertion, parse the numeric part of the computed CSS value, and compare it with Chai. For an inclusive width range from 280px through 360px:
cy.get('.card').should(($el) => {
const width = Number.parseFloat($el.css('width'))
expect(width).to.be.within(280, 360)
})
The callback keeps the read and assertion inside Cypress’s retry cycle, so the test can wait for styles applied after rendering, animation, or data loading. Cypress documents this behavior in its assertions reference, should() documentation, and get() command reference.
The basic pattern
$el.css('width') returns a CSS value as text, commonly a string such as "320px". Parse the numeric portion before using numeric Chai assertions:
describe('card layout', () => {
it('keeps the card width in the supported range', () => {
cy.visit('/products')
cy.get('.card').should(($el) => {
const width = Number.parseFloat($el.css('width'))
expect(width, 'card width').to.be.within(280, 360)
})
})
})
cy.get('.card') yields the element, while should(callbackFn) runs the explicit expect assertion. Cypress retries the callback until it passes or the command times out. That is preferable to reading the value once with a separate JavaScript expression when the page is still settling.
#1 Best Overall
Choose the rule your UI actually requires
Inclusive lower and upper bounds
within(min, max) accepts both endpoints. A value of exactly 280 or 360 passes:
cy.get('.card').should(($el) => {
const width = Number.parseFloat($el.css('width'))
expect(width).to.be.within(280, 360)
})
Chai defines this as greater than or equal to the start and less than or equal to the finish. See the Chai BDD API.
Exclusive bounds
Use greaterThan and lessThan when the endpoints must fail:
Free tools Windows power users keep installed
One-click scans. No signup required.
cy.get('.card').should(($el) => {
const width = Number.parseFloat($el.css('width'))
expect(width).to.be.greaterThan(280).and.lessThan(360)
})
Equivalent separate assertions can make failure messages clearer:
cy.get('.card').should(($el) => {
const width = Number.parseFloat($el.css('width'))
expect(width, 'width lower bound').to.be.greaterThan(280)
expect(width, 'width upper bound').to.be.lessThan(360)
})
A target with tolerance
If the requirement is “320px, with a small layout tolerance,” use closeTo(expected, delta). Chai treats the accepted interval as expected plus or minus delta:
cy.get('.card').should(($el) => {
const width = Number.parseFloat($el.css('width'))
expect(width).to.be.closeTo(320, 2)
})
Use this for a target measurement, not for a general minimum-to-maximum contract. Chai’s assert API documents the plus-or-minus tolerance behavior.
Rank #2
Explicit inclusive endpoint checks
at.least and at.most express the policy in words and let you attach a message to each side:
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →cy.get('.card').should(($el) => {
const width = Number.parseFloat($el.css('width'))
expect(width, 'minimum width').to.be.at.least(280)
expect(width, 'maximum width').to.be.at.most(360)
})
Keep units and value representation explicit
Check the unit when it is part of the contract
Parsing with Number.parseFloat intentionally discards the suffix. It proves the numeric portion, not that the original value used pixels. If the test contract requires a pixel value, read the string and check its suffix before comparing:
cy.get('.card').should(($el) => {
const cssWidth = $el.css('width')
expect(cssWidth, 'serialized width').to.match(/px$/)
const width = Number.parseFloat(cssWidth)
expect(width).to.be.within(280, 360)
})
This distinction matters for values expressed in rem, percentages, viewport units, or other valid CSS units. A numeric 20 is not automatically equivalent to 20px.
Computed CSS versus authored CSS
$el.css('width') is appropriate when the behavior under test is the rendered, computed layout. It can differ from the declaration written in a stylesheet because of inheritance, cascade, responsive rules, or layout calculation. The chai-jQuery plugin documents CSS assertions against computed values: chai-jQuery CSS assertion.
If the requirement concerns the source declaration itself rather than the rendered result, test that source through your stylesheet or component-level checks instead; a browser layout assertion should describe what the user sees.
Use exact CSS assertions only for exact strings
For a known serialized value, Cypress supports a direct assertion:
Rank #3
cy.get('.card').should('have.css', 'width', '320px')
This is useful when the exact string, including its unit, is the requirement. It is not a range assertion: the direct have.css form compares one value. For a numeric interval, use the callback form and Chai comparison shown above.
Make asynchronous rendering deterministic
Place both the CSS read and numeric comparison in the should callback. Cypress will invoke it again when the assertion fails, up to the command timeout, allowing styles to settle after an animation or data-driven render:
cy.get('[data-cy=results-card]').should(($card) => {
const width = Number.parseFloat($card.css('width'))
expect(width).to.be.within(280, 360)
})
Do not issue Cypress commands inside this callback. The callback is for synchronous inspection and explicit assertions; queue commands outside it. If the application can remain in an intermediate state indefinitely, first wait for a meaningful application signal (for example, a loaded marker), then perform the CSS assertion.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Animations and transitions
A transition can produce several legitimate intermediate widths. Decide whether the contract is about the settled state or every frame. For a settled-state test, disable or shorten transitions in the test environment, or wait for the application’s completed-state marker before asserting. Keeping the assertion in should still allows Cypress to retry while the final style is applied.
Responsive layouts
A range that is valid on desktop may be wrong on a phone. Fix the viewport and relevant state when the acceptable range depends on responsive CSS:
cy.viewport(1280, 800)
cy.visit('/products')
cy.get('.card').should(($el) => {
const width = Number.parseFloat($el.css('width'))
expect(width).to.be.within(280, 360)
})
For a responsive component, use separate tests with explicit viewport sizes and ranges instead of one broad interval that hides a breakpoint regression.
Rank #4
Guard against values that are not numbers
Many CSS properties can legitimately return auto, normal, none, or a calc() expression that is not directly comparable with parseFloat. A precondition makes the failure understandable:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minutecy.get('.panel').should(($el) => {
const cssWidth = $el.css('width')
expect(cssWidth, 'width must resolve to pixels').to.match(/^d+(?:.d+)?px$/)
const width = Number.parseFloat(cssWidth)
expect(width).to.be.within(280, 360)
})
If the browser returns a non-pixel computed value or the property is inherently non-numeric, test another observable: element geometry, visibility, a class indicating state, or an application-level value. Do not silently turn NaN into a passing result.
Geometry can be a better contract than a CSS string
When your real requirement is rendered size, an element’s bounding rectangle may be clearer than a serialized CSS property, especially when transforms or layout calculations are involved:
cy.get('.card').should(($el) => {
const width = $el[0].getBoundingClientRect().width
expect(width).to.be.within(280, 360)
})
This still belongs in the retryable callback. Choose CSS when you specifically need the computed property; choose geometry when you need the pixels occupied by the rendered element.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common failures and fixes
“expected ‘320px’ to be a number”
The value is still a string. Parse it first:
const width = Number.parseFloat($el.css('width'))
The assertion fails at a boundary
Check the policy. within, at.least, and at.most are inclusive. Replace them with greaterThan and lessThan for an exclusive interval.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →The value is “auto” or “normal”
That is not a numeric contract. Add a unit/value precondition, assert a different property, or measure the rendered rectangle.
The test sees an old width
Move the read into the should callback, wait for the application’s loaded state, and make the viewport and test data deterministic. Avoid a one-time read before the UI has rendered.
The result differs across machines
Control viewport dimensions, device scale assumptions, fonts, zoom, and responsive state. If fractional pixels are expected, use a documented tolerance rather than an arbitrary wide range.
A chained assertion is hard to diagnose
Split lower and upper checks and provide assertion messages. The first failing side then identifies whether the layout is too narrow or too wide.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePerformance, reliability, and maintainability
- Use a stable selector such as
data-cyrather than a class whose purpose is purely visual. - Keep the range narrow enough to catch regressions but wide enough to tolerate intentional fractional layout rounding.
- Store bounds as named constants when several tests share the same design contract.
- Test one representative component at each breakpoint instead of asserting every element’s width in every end-to-end test.
- Prefer an application signal over arbitrary sleeps; Cypress’s retryable assertion already waits for the condition.
- Document whether bounds are inclusive, which unit is required, and whether the value is computed CSS or rendered geometry.
Or skip the browser setup
If you need a screenshot of the resulting page for a visual record, bug report, or CI artifact, ScreenshotNeo can capture the URL through one request. It accepts consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
See the ScreenshotNeo documentation for all options. A direct call looks like this:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for ScreenshotNeo.
Frequently Asked Questions
Are Cypress CSS ranges inclusive by default?
Yes. Chai’s within(min, max), at.least(min), and at.most(max) include their endpoints.
Can I compare a percentage directly with a pixel range?
No. Define the unit contract first. Convert or measure a computed pixel result only when that conversion represents the behavior you intend to test.
What should I test when a CSS property resolves to calc()?
If the browser does not expose a directly numeric computed value, assert rendered geometry or another observable state instead of applying parseFloat to the expression.
The Bottom Line
Read the computed value inside a retryable should callback, parse its numeric portion, and choose inclusive, exclusive, or tolerance assertions to match the layout contract.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Recommended Free Tools

