diff options
author | Michał Gołębiowski-Owczarek <m.goleb@gmail.com> | 2025-02-24 18:43:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-24 18:43:56 +0100 |
commit | eca2a56457e1c40c071aeb3ac87efeb8bbb8013e (patch) | |
tree | f77efcb7e31da94fb46175abb113ce452399c24c /src | |
parent | e2fe97b7f15cf5ee2e44566b381f7bf214e491b1 (diff) | |
download | jquery-eca2a56457e1c40c071aeb3ac87efeb8bbb8013e.tar.gz jquery-eca2a56457e1c40c071aeb3ac87efeb8bbb8013e.zip |
CSS: Fix dimensions of table `<col>` elements
Changes:
1. Fix measurements of `<col span="2">` elements in Firefox.
2. Fix measurements of all implicitly sized `<col>` elements in Safari.
Firefox always reports computed width as if `span` was 1. In Safari, computed
width for columns is always 0. Work around both issues by using `offsetWidth`.
In IE/Edge, `<col>` computed width is `"auto"` unless `width` is set explicitly
via CSS so measurements there remain incorrect. Because of the lack of a proper
workaround, we accept this limitation.
Fixes gh-5628
Closes gh-5630
Ref gh-5634
Diffstat (limited to 'src')
-rw-r--r-- | src/css.js | 50 | ||||
-rw-r--r-- | src/css/support.js | 134 |
2 files changed, 101 insertions, 83 deletions
diff --git a/src/css.js b/src/css.js index 3e7073507..66e5c3c75 100644 --- a/src/css.js +++ b/src/css.js @@ -18,13 +18,7 @@ import { support } from "./css/support.js"; import "./core/init.js"; import "./core/ready.js"; -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, +var cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", fontWeight: "400" @@ -137,24 +131,22 @@ function getWidthOrHeight( elem, dimension, extra ) { } - if ( ( + if ( + ( + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - val === "auto" || + // Support: IE 9 - 11+ + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + ( isIE && isBorderBox ) || - // Support: IE 9 - 11+ - // Use offsetWidth/offsetHeight for when box sizing is unreliable. - // In those cases, the computed value can be trusted to be border-box. - ( isIE && isBorderBox ) || + ( !support.reliableColDimensions() && nodeName( elem, "col" ) ) || - // Support: IE 10 - 11+ - // IE misreports `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Support: Firefox 70 - 135+ - // Firefox includes border widths - // in computed dimensions for table rows. (gh-4529) - ( !support.reliableTrDimensions() && nodeName( elem, "tr" ) ) ) && + ( !support.reliableTrDimensions() && nodeName( elem, "tr" ) ) + ) && // Make sure the element is visible & connected elem.getClientRects().length ) { @@ -316,17 +308,9 @@ jQuery.each( [ "height", "width" ], function( _i, dimension ) { get: function( elem, computed, extra ) { if ( computed ) { - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - - // Support: Safari <=8 - 12+, Chrome <=73+ - // Table columns in WebKit/Blink have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11+ - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + // Elements with `display: none` can have dimension info if + // we invisibly show them. + return jQuery.css( elem, "display" ) === "none" ? swap( elem, cssShow, function() { return getWidthOrHeight( elem, dimension, extra ); } ) : diff --git a/src/css/support.js b/src/css/support.js index bca0b6dbf..a05d31bd1 100644 --- a/src/css/support.js +++ b/src/css/support.js @@ -1,62 +1,96 @@ +import { jQuery } from "../core.js"; import { document } from "../var/document.js"; import { documentElement } from "../var/documentElement.js"; import { support } from "../var/support.js"; +import { isIE } from "../var/isIE.js"; -( function() { +var reliableTrDimensionsVal, reliableColDimensionsVal, + table = document.createElement( "table" ); -var reliableTrDimensionsVal, - div = document.createElement( "div" ); +// Executing table tests requires only one layout, so they're executed +// at the same time to save the second computation. +function computeTableStyleTests() { + if ( -// Finish early in limited (non-browser) environments -if ( !div.style ) { - return; -} + // This is a singleton, we need to execute it only once + !table || + + // Finish early in limited (non-browser) environments + !table.style + ) { + return; + } + + var trStyle, + col = document.createElement( "col" ), + tr = document.createElement( "tr" ), + td = document.createElement( "td" ); -// Support: IE 10 - 11+ -// IE misreports `getComputedStyle` of table rows with width/height -// set in CSS while `offset*` properties report correct values. -// Support: Firefox 70+ -// Only Firefox includes border widths -// in computed dimensions. (gh-4529) -support.reliableTrDimensions = function() { - var table, tr, trStyle; - if ( reliableTrDimensionsVal == null ) { - table = document.createElement( "table" ); - tr = document.createElement( "tr" ); - - table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; - tr.style.cssText = "box-sizing:content-box;border:1px solid;height:1px"; - div.style.height = "9px"; - - // Support: Android Chrome 86+ - // In our bodyBackground.html iframe, - // display for all div elements is set to "inline", - // which causes a problem only in Android Chrome, but - // not consistently across all devices. - // Ensuring the div is `display: block` - // gets around this issue. - div.style.display = "block"; - - documentElement - .appendChild( table ) - .appendChild( tr ) - .appendChild( div ); - - // Don't run until window is visible - if ( table.offsetWidth === 0 ) { - documentElement.removeChild( table ); - return; - } - - trStyle = window.getComputedStyle( tr ); - reliableTrDimensionsVal = ( Math.round( parseFloat( trStyle.height ) ) + - Math.round( parseFloat( trStyle.borderTopWidth ) ) + - Math.round( parseFloat( trStyle.borderBottomWidth ) ) ) === tr.offsetHeight; + table.style.cssText = "position:absolute;left:-11111px;" + + "border-collapse:separate;border-spacing:0"; + tr.style.cssText = "box-sizing:content-box;border:1px solid;height:1px"; + td.style.cssText = "height:9px;width:9px;padding:0"; + col.span = 2; + + documentElement + .appendChild( table ) + .appendChild( col ) + .parentNode + .appendChild( tr ) + .appendChild( td ) + .parentNode + .appendChild( td.cloneNode( true ) ); + + // Don't run until window is visible + if ( table.offsetWidth === 0 ) { documentElement.removeChild( table ); + return; + } + + trStyle = window.getComputedStyle( tr ); + + // Support: Firefox 135+ + // Firefox always reports computed width as if `span` was 1. + // Support: Safari 18.3+ + // In Safari, computed width for columns is always 0. + // In both these browsers, using `offsetWidth` solves the issue. + // Support: IE 11+ + // In IE, `<col>` computed width is `"auto"` unless `width` is set + // explicitly via CSS so measurements there remain incorrect. Because of + // the lack of a proper workaround, we accept this limitation, treating + // IE as passing the test. + reliableColDimensionsVal = isIE || Math.round( parseFloat( + window.getComputedStyle( col ).width ) + ) === 18; + + // Support: IE 10 - 11+ + // IE misreports `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Support: Firefox 70 - 135+ + // Only Firefox includes border widths + // in computed dimensions for table rows. (gh-4529) + reliableTrDimensionsVal = Math.round( parseFloat( trStyle.height ) + + parseFloat( trStyle.borderTopWidth ) + + parseFloat( trStyle.borderBottomWidth ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + + // Nullify the table so it wouldn't be stored in the memory; + // it will also be a sign that checks were already performed. + table = null; +} + +jQuery.extend( support, { + reliableTrDimensions: function() { + computeTableStyleTests(); + return reliableTrDimensionsVal; + }, + + reliableColDimensions: function() { + computeTableStyleTests(); + return reliableColDimensionsVal; } - return reliableTrDimensionsVal; -}; -} )(); +} ); export { support }; |