summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-values
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /testing/web-platform/tests/css/css-values
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-values')
-rw-r--r--testing/web-platform/tests/css/css-values/META.yml8
-rw-r--r--testing/web-platform/tests/css/css-values/absolute-length-units-001.html35
-rw-r--r--testing/web-platform/tests/css/css-values/absolute_length_units.html77
-rw-r--r--testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-computed.html69
-rw-r--r--testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-invalid.html77
-rw-r--r--testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-serialize.html64
-rw-r--r--testing/web-platform/tests/css/css-values/angle-units-001.html43
-rw-r--r--testing/web-platform/tests/css/css-values/angle-units-002.html41
-rw-r--r--testing/web-platform/tests/css/css-values/angle-units-003.html41
-rw-r--r--testing/web-platform/tests/css/css-values/angle-units-004.html41
-rw-r--r--testing/web-platform/tests/css/css-values/angle-units-005.html41
-rw-r--r--testing/web-platform/tests/css/css-values/animations/calc-interpolation.html136
-rw-r--r--testing/web-platform/tests/css/css-values/animations/line-height-lh-transition.html32
-rw-r--r--testing/web-platform/tests/css/css-values/attr-color-invalid-cast.html43
-rw-r--r--testing/web-platform/tests/css/css-values/attr-color-invalid-fallback.html43
-rw-r--r--testing/web-platform/tests/css/css-values/attr-color-valid.html43
-rw-r--r--testing/web-platform/tests/css/css-values/attr-in-max.html28
-rw-r--r--testing/web-platform/tests/css/css-values/attr-invalid-type-001.html43
-rw-r--r--testing/web-platform/tests/css/css-values/attr-invalid-type-002.html46
-rw-r--r--testing/web-platform/tests/css/css-values/attr-invalid-type-008.html90
-rw-r--r--testing/web-platform/tests/css/css-values/attr-length-invalid-cast.html43
-rw-r--r--testing/web-platform/tests/css/css-values/attr-length-invalid-fallback.html43
-rw-r--r--testing/web-platform/tests/css/css-values/attr-length-valid-zero-nofallback.html46
-rw-r--r--testing/web-platform/tests/css/css-values/attr-length-valid-zero.html46
-rw-r--r--testing/web-platform/tests/css/css-values/attr-length-valid.html43
-rw-r--r--testing/web-platform/tests/css/css-values/attr-px-invalid-cast.html43
-rw-r--r--testing/web-platform/tests/css/css-values/attr-px-invalid-fallback.html43
-rw-r--r--testing/web-platform/tests/css/css-values/attr-px-valid.html43
-rw-r--r--testing/web-platform/tests/css/css-values/calc-angle-values.html157
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-image-gradient-1-ref.html20
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-image-gradient-1.html22
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-linear-gradient-1-ref.html37
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-linear-gradient-1.html40
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-position-002.html77
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-position-003.html76
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-position-1-ref.html24
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-position-1.html26
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-size-1-ref.html24
-rw-r--r--testing/web-platform/tests/css/css-values/calc-background-size-1.html26
-rw-r--r--testing/web-platform/tests/css/css-values/calc-border-radius-1-ref.html20
-rw-r--r--testing/web-platform/tests/css/css-values/calc-border-radius-1.html32
-rw-r--r--testing/web-platform/tests/css/css-values/calc-catch-divide-by-0.html47
-rw-r--r--testing/web-platform/tests/css/css-values/calc-ch-ex-lang-ref.html12
-rw-r--r--testing/web-platform/tests/css/css-values/calc-ch-ex-lang.html16
-rw-r--r--testing/web-platform/tests/css/css-values/calc-height-block-1-ref.html29
-rw-r--r--testing/web-platform/tests/css/css-values/calc-height-block-1.html35
-rw-r--r--testing/web-platform/tests/css/css-values/calc-height-table-1-ref.html28
-rw-r--r--testing/web-platform/tests/css/css-values/calc-height-table-1.html30
-rw-r--r--testing/web-platform/tests/css/css-values/calc-in-calc.html42
-rw-r--r--testing/web-platform/tests/css/css-values/calc-in-color-001.html26
-rw-r--r--testing/web-platform/tests/css/css-values/calc-in-counter-001-ref.xhtml27
-rw-r--r--testing/web-platform/tests/css/css-values/calc-in-counter-001.xhtml42
-rw-r--r--testing/web-platform/tests/css/css-values/calc-in-font-feature-settings.html22
-rw-r--r--testing/web-platform/tests/css/css-values/calc-in-max.html27
-rw-r--r--testing/web-platform/tests/css/css-values/calc-in-media-queries-001.html42
-rw-r--r--testing/web-platform/tests/css/css-values/calc-in-media-queries-002.html42
-rw-r--r--testing/web-platform/tests/css/css-values/calc-in-media-queries-with-mixed-units.html29
-rw-r--r--testing/web-platform/tests/css/css-values/calc-infinity-nan-computed.html77
-rw-r--r--testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-angle.html55
-rw-r--r--testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-length.html67
-rw-r--r--testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-resolution.html54
-rw-r--r--testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-time.html54
-rw-r--r--testing/web-platform/tests/css/css-values/calc-integer.html58
-rw-r--r--testing/web-platform/tests/css/css-values/calc-invalid-parsing.html9
-rw-r--r--testing/web-platform/tests/css/css-values/calc-invalid-range-clamping.html44
-rw-r--r--testing/web-platform/tests/css/css-values/calc-letter-spacing.html75
-rw-r--r--testing/web-platform/tests/css/css-values/calc-margin-block-1-ref.html21
-rw-r--r--testing/web-platform/tests/css/css-values/calc-margin-block-1.html23
-rw-r--r--testing/web-platform/tests/css/css-values/calc-max-height-block-1-ref.html29
-rw-r--r--testing/web-platform/tests/css/css-values/calc-max-height-block-1.html35
-rw-r--r--testing/web-platform/tests/css/css-values/calc-max-width-block-1.html25
-rw-r--r--testing/web-platform/tests/css/css-values/calc-max-width-block-intrinsic-1-ref.html21
-rw-r--r--testing/web-platform/tests/css/css-values/calc-max-width-block-intrinsic-1.html27
-rw-r--r--testing/web-platform/tests/css/css-values/calc-min-height-block-1.html35
-rw-r--r--testing/web-platform/tests/css/css-values/calc-min-height.html74
-rw-r--r--testing/web-platform/tests/css/css-values/calc-min-width-block-1.html25
-rw-r--r--testing/web-platform/tests/css/css-values/calc-min-width-block-intrinsic-1-ref.html21
-rw-r--r--testing/web-platform/tests/css/css-values/calc-min-width-block-intrinsic-1.html27
-rw-r--r--testing/web-platform/tests/css/css-values/calc-nesting-002.html78
-rw-r--r--testing/web-platform/tests/css/css-values/calc-nesting.html44
-rw-r--r--testing/web-platform/tests/css/css-values/calc-numbers.html98
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-absolute-bottom-1.html33
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-absolute-left-1.html23
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-absolute-right-1.html23
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-absolute-top-1-ref.html30
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-absolute-top-1.html33
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-relative-bottom-1.html32
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-relative-left-1-ref.html20
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-relative-left-1.html22
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-relative-right-1.html22
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-relative-top-1-ref.html30
-rw-r--r--testing/web-platform/tests/css/css-values/calc-offsets-relative-top-1.html32
-rw-r--r--testing/web-platform/tests/css/css-values/calc-padding-block-1-ref.html22
-rw-r--r--testing/web-platform/tests/css/css-values/calc-padding-block-1.html24
-rw-r--r--testing/web-platform/tests/css/css-values/calc-parenthesis-stack.html48
-rw-r--r--testing/web-platform/tests/css/css-values/calc-positive-fraction-001.html44
-rw-r--r--testing/web-platform/tests/css/css-values/calc-rem-lang-ref.html6
-rw-r--r--testing/web-platform/tests/css/css-values/calc-rem-lang.html17
-rw-r--r--testing/web-platform/tests/css/css-values/calc-rgb-percent-001.html38
-rw-r--r--testing/web-platform/tests/css/css-values/calc-rounding-001.html43
-rw-r--r--testing/web-platform/tests/css/css-values/calc-rounds-to-integer.html120
-rw-r--r--testing/web-platform/tests/css/css-values/calc-serialization-002.html139
-rw-r--r--testing/web-platform/tests/css/css-values/calc-serialization.html29
-rw-r--r--testing/web-platform/tests/css/css-values/calc-text-indent-1-ref.html23
-rw-r--r--testing/web-platform/tests/css/css-values/calc-text-indent-1.html25
-rw-r--r--testing/web-platform/tests/css/css-values/calc-text-indent-intrinsic-1-ref.html21
-rw-r--r--testing/web-platform/tests/css/css-values/calc-text-indent-intrinsic-1.html26
-rw-r--r--testing/web-platform/tests/css/css-values/calc-time-values.html104
-rw-r--r--testing/web-platform/tests/css/css-values/calc-transform-origin-1-ref.html25
-rw-r--r--testing/web-platform/tests/css/css-values/calc-transform-origin-1.html27
-rw-r--r--testing/web-platform/tests/css/css-values/calc-unit-analysis.html76
-rw-r--r--testing/web-platform/tests/css/css-values/calc-vertical-align-1-ref.html17
-rw-r--r--testing/web-platform/tests/css/css-values/calc-vertical-align-1.html19
-rw-r--r--testing/web-platform/tests/css/css-values/calc-width-block-1-ref.html23
-rw-r--r--testing/web-platform/tests/css/css-values/calc-width-block-1.html25
-rw-r--r--testing/web-platform/tests/css/css-values/calc-width-block-intrinsic-1-ref.html21
-rw-r--r--testing/web-platform/tests/css/css-values/calc-width-block-intrinsic-1.html26
-rw-r--r--testing/web-platform/tests/css/css-values/calc-width-table-auto-1-ref.html27
-rw-r--r--testing/web-platform/tests/css/css-values/calc-width-table-auto-1.html29
-rw-r--r--testing/web-platform/tests/css/css-values/calc-width-table-fixed-1-ref.html32
-rw-r--r--testing/web-platform/tests/css/css-values/calc-width-table-fixed-1.html34
-rw-r--r--testing/web-platform/tests/css/css-values/calc-z-index-fractions-001.html58
-rw-r--r--testing/web-platform/tests/css/css-values/calc-zero-percent-height.html30
-rw-r--r--testing/web-platform/tests/css/css-values/cap-unit-001.html32
-rw-r--r--testing/web-platform/tests/css/css-values/ch-empty-pseudo-recalc-on-font-load.html70
-rw-r--r--testing/web-platform/tests/css/css-values/ch-pseudo-recalc-on-font-load.html89
-rw-r--r--testing/web-platform/tests/css/css-values/ch-recalc-on-font-load.html79
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-001.html36
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-002.html39
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-003.html37
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-004.html37
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-008.html38
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-009.html39
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-010.html41
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-011.html41
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-012.html41
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-016.html30
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-017.html32
-rw-r--r--testing/web-platform/tests/css/css-values/ch-unit-018.html35
-rw-r--r--testing/web-platform/tests/css/css-values/clamp-length-computed.html34
-rw-r--r--testing/web-platform/tests/css/css-values/clamp-length-invalid.html24
-rw-r--r--testing/web-platform/tests/css/css-values/clamp-length-serialize.html15
-rw-r--r--testing/web-platform/tests/css/css-values/crashtests/viewport-unit-inline-style-crash.html11
-rw-r--r--testing/web-platform/tests/css/css-values/dynamic-viewport-units-rule-cache.html59
-rw-r--r--testing/web-platform/tests/css/css-values/ex-calc-expression-001-ref.html11
-rw-r--r--testing/web-platform/tests/css/css-values/ex-calc-expression-001.html19
-rw-r--r--testing/web-platform/tests/css/css-values/ex-unit-001.html36
-rw-r--r--testing/web-platform/tests/css/css-values/ex-unit-002.html30
-rw-r--r--testing/web-platform/tests/css/css-values/ex-unit-003.html31
-rw-r--r--testing/web-platform/tests/css/css-values/ex-unit-004.html35
-rw-r--r--testing/web-platform/tests/css/css-values/exp-log-compute.html35
-rw-r--r--testing/web-platform/tests/css/css-values/exp-log-invalid.html65
-rw-r--r--testing/web-platform/tests/css/css-values/exp-log-serialize.html40
-rw-r--r--testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-001.html95
-rw-r--r--testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-002.html80
-rw-r--r--testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-003.html81
-rw-r--r--testing/web-platform/tests/css/css-values/getComputedStyle-calc-mixed-units-001.html110
-rw-r--r--testing/web-platform/tests/css/css-values/hypot-pow-sqrt-computed.html63
-rw-r--r--testing/web-platform/tests/css/css-values/hypot-pow-sqrt-invalid.html68
-rw-r--r--testing/web-platform/tests/css/css-values/hypot-pow-sqrt-serialize.html43
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-001.html43
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-002.html47
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-003.html47
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-004.html47
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-008.html55
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-009.html55
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-010.html56
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-011.html56
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-012.html56
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-013.html34
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-014.html41
-rw-r--r--testing/web-platform/tests/css/css-values/ic-unit-015.html35
-rw-r--r--testing/web-platform/tests/css/css-values/integer_interpolation_round_half_towards_positive_infinity_order.html39
-rw-r--r--testing/web-platform/tests/css/css-values/integer_interpolation_round_half_towards_positive_infinity_z_index.html38
-rw-r--r--testing/web-platform/tests/css/css-values/lh-rlh-on-root-001.html86
-rw-r--r--testing/web-platform/tests/css/css-values/lh-unit-001.html26
-rw-r--r--testing/web-platform/tests/css/css-values/lh-unit-002.html26
-rw-r--r--testing/web-platform/tests/css/css-values/lh-unit-003.html42
-rw-r--r--testing/web-platform/tests/css/css-values/lh-unit-004.html18
-rw-r--r--testing/web-platform/tests/css/css-values/line-break-ch-unit.html52
-rw-r--r--testing/web-platform/tests/css/css-values/max-20-arguments.html27
-rw-r--r--testing/web-platform/tests/css/css-values/max-length-percent-001.html26
-rw-r--r--testing/web-platform/tests/css/css-values/max-unitless-zero-invalid.html33
-rw-r--r--testing/web-platform/tests/css/css-values/min-length-percent-001.html26
-rw-r--r--testing/web-platform/tests/css/css-values/min-max-percentage-length-interpolation.html43
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-angle-computed.html59
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-angle-invalid.html69
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-angle-serialize.html111
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-integer-computed.html35
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-length-computed.html114
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-length-invalid.html66
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-length-percent-computed.html74
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-length-percent-invalid.html36
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-length-percent-serialize.html126
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-length-serialize.html75
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-number-computed.html30
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-number-invalid.html65
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-number-serialize.html63
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-percentage-computed.html33
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-percentage-invalid.html65
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-percentage-serialize.html72
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-time-computed.html48
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-time-invalid.html69
-rw-r--r--testing/web-platform/tests/css/css-values/minmax-time-serialize.html64
-rw-r--r--testing/web-platform/tests/css/css-values/negative-calc-to-non-negative-integer-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-values/negative-calc-to-non-negative-integer.html18
-rw-r--r--testing/web-platform/tests/css/css-values/percentage-rem-low.html22
-rw-r--r--testing/web-platform/tests/css/css-values/q-unit-case-insensitivity-001.html46
-rw-r--r--testing/web-platform/tests/css/css-values/q-unit-case-insensitivity-002.html46
-rw-r--r--testing/web-platform/tests/css/css-values/rch-invalidation.html36
-rw-r--r--testing/web-platform/tests/css/css-values/reference/200-200-green.html33
-rw-r--r--testing/web-platform/tests/css/css-values/reference/all-green.html1
-rw-r--r--testing/web-platform/tests/css/css-values/reference/cap-unit-001-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ch-unit-001-ref.html11
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ch-unit-002-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ch-unit-008-ref.html35
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ch-unit-009-ref.html35
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ch-unit-011-ref.html36
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ch-unit-016-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ex-unit-001-ref.html27
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ex-unit-002-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ex-unit-004-ref.html17
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ic-unit-001-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ic-unit-002-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ic-unit-008-ref.html50
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ic-unit-009-ref.html50
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ic-unit-012-ref.html51
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ic-unit-013-ref.html19
-rw-r--r--testing/web-platform/tests/css/css-values/reference/ic-unit-014-ref.html19
-rw-r--r--testing/web-platform/tests/css/css-values/reference/vh-support-atviewport-ref.htm22
-rw-r--r--testing/web-platform/tests/css/css-values/reference/vh_not_refreshing_on_chrome-ref.html65
-rw-r--r--testing/web-platform/tests/css/css-values/reference/vh_not_refreshing_on_chrome_iframe-ref.html79
-rw-r--r--testing/web-platform/tests/css/css-values/reference/viewport-unit-011-ref.html19
-rw-r--r--testing/web-platform/tests/css/css-values/rem-root-font-size-restyle-1-ref.html15
-rw-r--r--testing/web-platform/tests/css/css-values/rem-root-font-size-restyle-1.html22
-rw-r--r--testing/web-platform/tests/css/css-values/rem-unit-root-element.html26
-rw-r--r--testing/web-platform/tests/css/css-values/resources/ChTestShortZero.woffbin0 -> 1152 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/resources/ChTestZeroWidthZero.woffbin0 -> 1056 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/resources/ExTest-NoSpace.woffbin0 -> 960 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/resources/ExTest.woffbin0 -> 924 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/resources/IcTestFullWidth.woff2bin0 -> 612 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/resources/IcTestHalfWidth.woff2bin0 -> 612 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/resources/IcTestZeroWidth.woff2bin0 -> 616 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/rex-invalidation.html37
-rw-r--r--testing/web-platform/tests/css/css-values/rgba-011.html53
-rw-r--r--testing/web-platform/tests/css/css-values/ric-invalidation.html36
-rw-r--r--testing/web-platform/tests/css/css-values/rlh-invalidation.html42
-rw-r--r--testing/web-platform/tests/css/css-values/round-function.html97
-rw-r--r--testing/web-platform/tests/css/css-values/round-mod-rem-computed.html150
-rw-r--r--testing/web-platform/tests/css/css-values/round-mod-rem-invalid.html94
-rw-r--r--testing/web-platform/tests/css/css-values/round-mod-rem-serialize.html44
-rw-r--r--testing/web-platform/tests/css/css-values/signs-abs-computed.html184
-rw-r--r--testing/web-platform/tests/css/css-values/signs-abs-invalid.html61
-rw-r--r--testing/web-platform/tests/css/css-values/signs-abs-serialize.html87
-rw-r--r--testing/web-platform/tests/css/css-values/sin-cos-tan-computed.html38
-rw-r--r--testing/web-platform/tests/css/css-values/sin-cos-tan-invalid.html58
-rw-r--r--testing/web-platform/tests/css/css-values/sin-cos-tan-serialize.html58
-rw-r--r--testing/web-platform/tests/css/css-values/support/1x1-green.pngbin0 -> 135 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/1x1-lime.pngbin0 -> 135 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/1x1-maroon.pngbin0 -> 109 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/1x1-navy.pngbin0 -> 109 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/1x1-red.pngbin0 -> 135 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/1x1-white.pngbin0 -> 109 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/60x60-gg-rr.pngbin0 -> 224 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/60x60-green.pngbin0 -> 218 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/README28
-rw-r--r--testing/web-platform/tests/css/css-values/support/a-green.css1
-rw-r--r--testing/web-platform/tests/css/css-values/support/b-green.css1
-rw-r--r--testing/web-platform/tests/css/css-values/support/blue-32x32.pngbin0 -> 110 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/c-red.css1
-rw-r--r--testing/web-platform/tests/css/css-values/support/cat.pngbin0 -> 1883 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/import-green.css1
-rw-r--r--testing/web-platform/tests/css/css-values/support/import-red.css1
-rw-r--r--testing/web-platform/tests/css/css-values/support/mixed-units-01.html23
-rw-r--r--testing/web-platform/tests/css/css-values/support/mixed-units-02.html23
-rw-r--r--testing/web-platform/tests/css/css-values/support/mixed-units-03.html23
-rw-r--r--testing/web-platform/tests/css/css-values/support/mixed-units-04.html23
-rw-r--r--testing/web-platform/tests/css/css-values/support/mixed-units-05.html23
-rw-r--r--testing/web-platform/tests/css/css-values/support/mixed-units-06.html23
-rw-r--r--testing/web-platform/tests/css/css-values/support/pattern-grg-rgr-grg.pngbin0 -> 222 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/pattern-grg-rrg-rgg.pngbin0 -> 231 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/pattern-rgr-grg-rgr.pngbin0 -> 223 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/pattern-tr.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/ruler-h-50%.pngbin0 -> 691 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/ruler-h-50px.pngbin0 -> 671 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/ruler-v-100px.pngbin0 -> 760 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/ruler-v-50px.pngbin0 -> 757 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/square-purple.pngbin0 -> 92 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/square-teal.pngbin0 -> 92 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/square-white.pngbin0 -> 78 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/support/README4
-rw-r--r--testing/web-platform/tests/css/css-values/support/support/swatch-green.pngbin0 -> 84 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/support/swatch-red.pngbin0 -> 84 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/swatch-blue.pngbin0 -> 84 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/swatch-green.pngbin0 -> 84 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/swatch-lime.pngbin0 -> 84 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/swatch-orange.pngbin0 -> 84 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/swatch-red.pngbin0 -> 84 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/swatch-teal.pngbin0 -> 156 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/swatch-white.pngbin0 -> 85 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/swatch-yellow.pngbin0 -> 84 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/test-bl.pngbin0 -> 1368 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/test-br.pngbin0 -> 1045 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/test-inner-half-size.pngbin0 -> 180 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/test-outer.pngbin0 -> 2412 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/test-tl.pngbin0 -> 1025 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/test-tr.pngbin0 -> 1235 bytes
-rw-r--r--testing/web-platform/tests/css/css-values/support/vh-support-transform-origin-iframe.html52
-rw-r--r--testing/web-platform/tests/css/css-values/support/vh-support-transform-translate-iframe.html51
-rw-r--r--testing/web-platform/tests/css/css-values/support/vh_not_refreshing_on_chrome_iframe.html93
-rw-r--r--testing/web-platform/tests/css/css-values/update-subpixel-rem-unit.html21
-rw-r--r--testing/web-platform/tests/css/css-values/urls/empty.html39
-rw-r--r--testing/web-platform/tests/css/css-values/urls/fragment-only.html40
-rw-r--r--testing/web-platform/tests/css/css-values/urls/resolve-relative-to-base.sub.html35
-rw-r--r--testing/web-platform/tests/css/css-values/urls/resolve-relative-to-stylesheet.html33
-rw-r--r--testing/web-platform/tests/css/css-values/urls/support/empty-urls.css9
-rw-r--r--testing/web-platform/tests/css/css-values/urls/support/fragment-only-urls.css19
-rw-r--r--testing/web-platform/tests/css/css-values/urls/support/relative-urls.css15
-rw-r--r--testing/web-platform/tests/css/css-values/vh-calc-support-pct.html43
-rw-r--r--testing/web-platform/tests/css/css-values/vh-calc-support.html43
-rw-r--r--testing/web-platform/tests/css/css-values/vh-em-inherit.html41
-rw-r--r--testing/web-platform/tests/css/css-values/vh-inherit.html42
-rw-r--r--testing/web-platform/tests/css/css-values/vh-interpolate-pct.html48
-rw-r--r--testing/web-platform/tests/css/css-values/vh-interpolate-px.html48
-rw-r--r--testing/web-platform/tests/css/css-values/vh-interpolate-vh.html48
-rw-r--r--testing/web-platform/tests/css/css-values/vh-support-margin.html41
-rw-r--r--testing/web-platform/tests/css/css-values/vh-support-transform-origin.html42
-rw-r--r--testing/web-platform/tests/css/css-values/vh-support-transform-translate.html42
-rw-r--r--testing/web-platform/tests/css/css-values/vh-support.html39
-rw-r--r--testing/web-platform/tests/css/css-values/vh-zero-support.html41
-rw-r--r--testing/web-platform/tests/css/css-values/vh_not_refreshing_on_chrome.html70
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-relative-lengths-scaled-viewport.html50
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-unit-011.html29
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-001-print-ref.html13
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-001-print.html17
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-after-font-load.html43
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-compute.html76
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-css2-001.html234
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-invalidation.html69
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-keyframes.html69
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-media-queries.html77
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-modify.html19
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-parsing.html28
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-writing-mode-font-size-ref.html27
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-writing-mode-font-size.html35
-rw-r--r--testing/web-platform/tests/css/css-values/viewport-units-writing-mode.html60
346 files changed, 13031 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-values/META.yml b/testing/web-platform/tests/css/css-values/META.yml
new file mode 100644
index 0000000000..a22882a999
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/META.yml
@@ -0,0 +1,8 @@
+spec: https://drafts.csswg.org/css-values/
+suggested_reviewers:
+ - frivoal
+ - dbaron
+ - FremyCompany
+ - plinss
+ - tabatkins
+ - fantasai
diff --git a/testing/web-platform/tests/css/css-values/absolute-length-units-001.html b/testing/web-platform/tests/css/css-values/absolute-length-units-001.html
new file mode 100644
index 0000000000..22b4390bde
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/absolute-length-units-001.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>absolute length units test</title>
+<meta name="author" title="Hwanseung Lee" href="mailto:hs1217.lee@samsung.com">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#absolute-lengths"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #t1 { width: 96px; height: 2.54cm; }
+ #t2 { width: 2.54cm; height: 25.4mm; }
+ #t3 { width: 25.4mm; height: 101.6q; }
+ #t4 { width: 101.6q; height: 1in; }
+ #t5 { width: 1in; height: 6pc; }
+ #t6 { width: 6pc; height: 72pt; }
+ #t7 { width: 72pt; height: 96px; }
+</style>
+
+<div id="t1"> </div>
+<div id="t2"> </div>
+<div id="t3"> </div>
+<div id="t4"> </div>
+<div id="t5"> </div>
+<div id="t6"> </div>
+<div id="t7"> </div>
+
+<script>
+ var test_items = ["t1", "t2", "t3", "t4", "t5", "t6", "t7"]
+
+ for (var i = 0; i < test_items.length; i++) {
+ test(function(){
+ var elem = document.getElementById(test_items[i]);
+ assert_equals(getComputedStyle(elem).width, getComputedStyle(elem).height, elem.id);
+ }, test_items[i])
+ }
+</script>
diff --git a/testing/web-platform/tests/css/css-values/absolute_length_units.html b/testing/web-platform/tests/css/css-values/absolute_length_units.html
new file mode 100644
index 0000000000..7528bbbbd4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/absolute_length_units.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<!-- Submitted from TestTWF Paris -->
+<head>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: elements should be the real world size given in mm, cm, inches...</title>
+ <link rel="author" title="Marc Bourlon" href="mailto:marc@bourlon.com">
+ <link rel="help" href="https://www.w3.org/TR/css3-values/#absolute-lengths" title="5.2 Absolute lengths: the cm, mm, Q, in, pt, pc, px units">
+
+ <style type="text/css">
+
+ .s1mm { background-color: fuchsia; width: 1mm; height: 1mm; }
+ .s10mm { background-color: olive; width: 10mm; height: 10mm; }
+ .s1cm { background-color: orange; width: 1cm; height: 1cm; }
+ .s254cm { background-color: gray; width: 2.54cm; height: 2.54cm; }
+ .s1in { background-color: blue; width: 1in; height: 1in; }
+
+ .inline { float: left; }
+
+ .newline { clear: left; }
+
+ p { clear: both; margin: 10px 0; }
+
+ </style>
+
+</head>
+<body>
+
+<p>
+ There should be a 1mm (width) by 1mm (height) fuchsia square:
+</p>
+
+<div class="s1mm"></div>
+
+<p>
+ There should be a 10mm (width) by 1mm (height) fuchsia stripe:
+</p>
+
+<div class="s1mm newline inline"></div>
+<div class="s1mm inline"></div>
+<div class="s1mm inline"></div>
+<div class="s1mm inline"></div>
+<div class="s1mm inline"></div>
+<div class="s1mm inline"></div>
+<div class="s1mm inline"></div>
+<div class="s1mm inline"></div>
+<div class="s1mm inline"></div>
+<div class="s1mm inline"></div>
+
+<p>
+ There should be a 10mm (width) by 10mm (height) olive square:
+</p>
+
+<div class="s10mm newline "></div>
+
+<p>
+ There should be a 1cm (width) by 1cm (height) orange square. So, same width above:
+</p>
+
+<div class="s1cm newline "></div>
+
+<p>
+ There should be a 2.54cm (width) by 2.54cm (height) gray square:
+</p>
+
+<div class="s254cm newline "></div>
+
+<p>
+ There should be a 1in (width) by 1in (height) blue square. So, same width as above:
+</p>
+
+<div class="s1in"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-computed.html b/testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-computed.html
new file mode 100644
index 0000000000..51e51770cf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-computed.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<script>
+function test_angle_equals(value, expected) {
+ test_math_used(`rotate(${value})`, `rotate(${expected})`,
+ {prop:'transform', base:'none',
+ msg: `${value} should be used-value-equivalent to ${expected}`});
+}
+// Simple tests
+test_angle_equals('acos(1)', '0deg');
+test_angle_equals('atan(0)', '0deg');
+test_angle_equals('asin(0)', '0deg');
+test_angle_equals('atan2(0,0)', '0deg');
+
+// Test pi
+test_math_used('calc(asin(sin(pi/2)))', '90deg', {type:'angle', approx:0.1});
+test_math_used('calc(acos(cos(pi - 3.14159265358979323846)))', '0deg', {type:'angle', approx:0.1});
+
+// Test e
+test_math_used('calc(atan(e - 2.7182818284590452354) )', '0deg', {type:'angle', approx:0.1});
+
+// General calculations
+test_math_used('calc(asin(sin(30deg + 1.0471967rad ) ))', '90deg', {type:'angle', approx:0.1});
+test_math_used('calc(acos(cos(30deg - 0.523599rad ) ))', '0deg'), {type:'angle', approx:0.1};
+test_math_used('calc(asin(sin(3.14159 / 2 + 1 - 1) ))', '90deg', {type:'angle', approx:0.1});
+test_math_used('calc(asin(sin(100grad) ))', '90deg', {type:'angle', approx:0.1});
+test_math_used('calc(acos(cos(0 / 2 + 1 - 1) ))', '0deg', {type:'angle', approx:0.1});
+test_math_used('calc(atan(tan(30deg + 0.261799rad ) ))', '45deg', {type:'angle', approx:0.1});
+test_math_used('calc(atan(tan(0.7853975rad ) ))', '45deg', {type:'angle', approx:0.1});
+test_math_used('calc(atan(tan(3.14159 / 4 + 1 - 1) ))', '45deg', {type:'angle', approx:0.1});
+test_math_used('calc(asin(sin(0.25turn)) )', '90deg', {type:'angle', approx:0.1});
+test_math_used('calc(atan2(0,1))', '0deg', {type:'angle', approx:0.1});
+test_math_used('calc(atan2(0,-1) / 4)', '45deg', {type:'angle', approx:0.1}); // atan2(0,-1) equals 180deg, result is divided to avoid ambiguity with -180deg
+test_math_used('calc(atan2(1,-1))', '135deg', {type:'angle', approx:0.1});
+test_math_used('calc(atan2(-1,1))', '-45deg', {type:'angle', approx:0.1});
+
+// Test nesting
+test_math_used('calc(cos(sin(acos(cos(pi)))))', '1', {type:'number', approx:0.1});
+test_math_used('calc(sin(atan(tan(pi/2))))', '1', {type:'number', approx:0.1});
+
+// Test types for atan2
+test_math_used('atan2(1px, -1px)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1cm, -1cm)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1mm, -1mm)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1Q, -1Q)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1in, -1in)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1pc, -1pc)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1pt, -1pt)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1em, -1em)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1ex, -1ex)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1ch, -1ch)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1rem, -1rem)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1vh, -1vh)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1vw, -1vw)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1deg, -1deg)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1grad, -1grad)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1turn, -1turn)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1rad, -1rad)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1s, -1s)', '135deg', {type:'angle', approx:0.1});
+test_math_used('atan2(1ms, -1ms)', '135deg', {type:'angle', approx:0.1});
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-invalid.html b/testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-invalid.html
new file mode 100644
index 0000000000..2f94c49ac8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-invalid.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#angles">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_angle(value) {
+ test_invalid_value('transform', `rotate(${value})`);
+}
+
+// Syntax checking
+test_invalid_angle('asin()');
+test_invalid_angle('asin( )');
+test_invalid_angle('asin(,)');
+test_invalid_angle('asin(1dag)');
+test_invalid_angle('asin(1deg, )');
+test_invalid_angle('asin(, 1deg)');
+test_invalid_angle('asin(1deg + )');
+test_invalid_angle('asin(1deg - )');
+test_invalid_angle('asin(1deg * )');
+test_invalid_angle('asin(1deg / )');
+test_invalid_angle('asin(1deg 2deg)');
+test_invalid_angle('asin(1deg, , 2deg)');
+test_invalid_angle('acos()');
+test_invalid_angle('acos( )');
+test_invalid_angle('acos(,)');
+test_invalid_angle('acos(1dag)');
+test_invalid_angle('acos(1deg, )');
+test_invalid_angle('acos(, 1deg)');
+test_invalid_angle('acos(1deg + )');
+test_invalid_angle('acos(1deg - )');
+test_invalid_angle('acos(1deg * )');
+test_invalid_angle('acos(1deg / )');
+test_invalid_angle('acos(1deg 2deg)');
+test_invalid_angle('acos(1deg, , 2deg)');
+test_invalid_angle('atan()');
+test_invalid_angle('atan( )');
+test_invalid_angle('atan(,)');
+test_invalid_angle('atan(1dag)');
+test_invalid_angle('atan(1deg, )');
+test_invalid_angle('atan(, 1deg)');
+test_invalid_angle('atan(1deg + )');
+test_invalid_angle('atan(1deg - )');
+test_invalid_angle('atan(1deg * )');
+test_invalid_angle('atan(1deg / )');
+test_invalid_angle('atan(1deg 2deg)');
+test_invalid_angle('atan(1deg, , 2deg)');
+test_invalid_angle('asin(90px)');
+test_invalid_angle('asin(30deg + 1.0471967rad, 0)');
+test_invalid_angle('acos( 0 ,)');
+test_invalid_angle('acos( () 30deg - 0.523599rad )');
+test_invalid_angle('atan(45deg )');
+test_invalid_angle('atan(30deg, + 0.261799rad)');
+test_invalid_angle('atan2()');
+test_invalid_angle('atan2( )');
+test_invalid_angle('atan2(,)');
+test_invalid_angle('atan2(1dag)');
+test_invalid_angle('atan2(1deg, )');
+test_invalid_angle('atan2(, 1deg)');
+test_invalid_angle('atan2(1deg + )');
+test_invalid_angle('atan2(1deg - )');
+test_invalid_angle('atan2(1deg * )');
+test_invalid_angle('atan2(1deg / )');
+test_invalid_angle('atan2(1deg 2deg)');
+test_invalid_angle('atan2(1deg, , 2deg)');
+test_invalid_angle('atan2(90px)');
+test_invalid_angle('atan2(90px, 100%)');
+
+test_invalid_angle('atan2(30deg + 1.0471967rad, 0)');
+test_invalid_angle('atan2( 0 ,)');
+test_invalid_angle('atan2( () 30deg - 0.523599rad )');
+test_invalid_angle('atan2(45deg )');
+test_invalid_angle('atan2(30deg, + 0.261799rad)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-serialize.html b/testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-serialize.html
new file mode 100644
index 0000000000..c867f34d47
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/acos-asin-atan-atan2-serialize.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#angles">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Apple Inc">
+<link rel="author" title="Seokho Song" href="seokho@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+
+function test_serialization(specified, expected, {prop="transform"}={}) {
+
+ // We only test the specified serialization,
+ // and not the computed or used serialization,
+ // since we'd need to do that by retrieving the rotation matrix,
+ // and that isn't perfectly interoperable in corner cases.
+ // Plus the point of this test is to check the trig functions themselves.
+ test_specified_serialization(prop, `rotate(${specified})`, `rotate(${expected})`)
+}
+//TEST CASE | EXPECTED
+var test_map = {
+ "acos(1)" :"calc(0deg)",
+ "acos(-1)" :"calc(180deg)",
+ "acos(-1.5)" :"calc(NaN * 1deg)",
+ "acos(1.5)" :"calc(NaN * 1deg)",
+ "acos(2)" :"calc(NaN * 1deg)",
+ "acos(0.5)" :"calc(60deg)",
+ "acos(1 - 0.5)" :"calc(60deg)",
+ "acos(0)" :"calc(90deg)",
+ "asin(1)" :"calc(90deg)",
+ "asin(-1)" :"calc(-90deg)",
+ "asin(-1.5)" :"calc(NaN * 1deg)",
+ "asin(1.5)" :"calc(NaN * 1deg)",
+ "asin(2)" :"calc(NaN * 1deg)",
+ "asin(0.5)" :"calc(30deg)",
+ "asin(1 - 0.5)" :"calc(30deg)",
+ "asin(0)" :"calc(0deg)",
+ "acos(pi - pi)" :"calc(90deg)",
+ "asin(pi - pi + 1)" :"calc(90deg)",
+ "atan(1)" :"calc(45deg)",
+ "atan(0.5)" :"calc(26.5651deg)",
+ "atan(0.577350269)" :"calc(30deg)",
+ "atan(0)" :"calc(0deg)",
+ "atan(infinity)" :"calc(90deg)",
+ "atan(tan(90deg))" :"calc(90deg)",
+ "atan(tan(-90deg))" :"calc(-90deg)",
+ "atan2(37.320508075, 10)" :"calc(75deg)",
+ "atan2(1s, 1000ms)" :"calc(45deg)",
+ "atan2(infinity, infinity)" :"calc(45deg)",
+ "atan2(-infinity, -infinity)" :"calc(-135deg)",
+ "atan2(infinity, 10)" :"calc(90deg)",
+ "atan2(10, infinity)" :"calc(0deg)",
+ "atan2(NaN, 10)" :"calc(NaN * 1deg)",
+ "atan2(10, NaN)" :"calc(NaN * 1deg)",
+ "atan2(NaN, NaN)" :"calc(NaN * 1deg)",
+};
+
+for (var exp in test_map) {
+ test_serialization(exp, test_map[exp]);
+ test_serialization(`calc(${exp})`, test_map[exp]);
+}
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/angle-units-001.html b/testing/web-platform/tests/css/css-values/angle-units-001.html
new file mode 100644
index 0000000000..38918d0439
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/angle-units-001.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: invalid angle units</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#angles">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <meta name="flags" content="invalid">
+ <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-4000">
+
+ <style>
+ div
+ {
+ height: 100px;
+ width: 100px;
+ }
+
+ div#test-overlapping-green
+ {
+ background-image: linear-gradient(green, green);
+ background-image: linear-gradient(90degree, red, red); /* invalid; 90deg is valid */
+ background-image: linear-gradient(100gradian, red, red); /* invalid; 100grad is valid */
+ background-image: linear-gradient(1.57radian, red, red); /* invalid; 1.57rad is valid */
+ background-image: linear-gradient(0.25turns, red, red); /* invalid; 0.25turn is valid */
+ }
+
+ div#reference-overlapped-red
+ {
+ background-color: red;
+ bottom: 100px;
+ position: relative;
+ z-index: -1;
+ }
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="test-overlapping-green"></div>
+
+ <div id="reference-overlapped-red"></div>
diff --git a/testing/web-platform/tests/css/css-values/angle-units-002.html b/testing/web-platform/tests/css/css-values/angle-units-002.html
new file mode 100644
index 0000000000..fa00b01dc0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/angle-units-002.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: degree angle unit with mixed case</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#angles">
+ <link rel="help" href="https://www.w3.org/TR/CSS22/syndata.html#characters">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-4000">
+ <meta content="This test checks that 'deg' angle unit is case-insensitive." name="assert">
+
+ <style>
+ div
+ {
+ height: 100px;
+ width: 100px;
+ }
+
+ div#test-overlapping-green
+ {
+ background-color: red;
+ background-image: linear-gradient(90DeG, green, green);
+ }
+
+ div#reference-overlapped-red
+ {
+ background-color: red;
+ bottom: 100px;
+ position: relative;
+ z-index: -1;
+ }
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="test-overlapping-green"></div>
+
+ <div id="reference-overlapped-red"></div>
diff --git a/testing/web-platform/tests/css/css-values/angle-units-003.html b/testing/web-platform/tests/css/css-values/angle-units-003.html
new file mode 100644
index 0000000000..9ac677aad7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/angle-units-003.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: grad angle unit with mixed case</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#angles">
+ <link rel="help" href="https://www.w3.org/TR/CSS22/syndata.html#characters">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-4000">
+ <meta content="This test checks that 'grad' angle unit is case-insensitive." name="assert">
+
+ <style>
+ div
+ {
+ height: 100px;
+ width: 100px;
+ }
+
+ div#test-overlapping-green
+ {
+ background-color: red;
+ background-image: linear-gradient(100gRaD, green, green);
+ }
+
+ div#reference-overlapped-red
+ {
+ background-color: red;
+ bottom: 100px;
+ position: relative;
+ z-index: -1;
+ }
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="test-overlapping-green"></div>
+
+ <div id="reference-overlapped-red"></div>
diff --git a/testing/web-platform/tests/css/css-values/angle-units-004.html b/testing/web-platform/tests/css/css-values/angle-units-004.html
new file mode 100644
index 0000000000..e1069a75cc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/angle-units-004.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: rad angle unit with mixed case</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#angles">
+ <link rel="help" href="https://www.w3.org/TR/CSS22/syndata.html#characters">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-4000">
+ <meta content="This test checks that 'rad' angle unit is case-insensitive." name="assert">
+
+ <style>
+ div
+ {
+ height: 100px;
+ width: 100px;
+ }
+
+ div#test-overlapping-green
+ {
+ background-color: red;
+ background-image: linear-gradient(1.57rAd, green, green);
+ }
+
+ div#reference-overlapped-red
+ {
+ background-color: red;
+ bottom: 100px;
+ position: relative;
+ z-index: -1;
+ }
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="test-overlapping-green"></div>
+
+ <div id="reference-overlapped-red"></div>
diff --git a/testing/web-platform/tests/css/css-values/angle-units-005.html b/testing/web-platform/tests/css/css-values/angle-units-005.html
new file mode 100644
index 0000000000..e67a3982f4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/angle-units-005.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: turn angle unit with mixed case</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#angles">
+ <link rel="help" href="https://www.w3.org/TR/CSS22/syndata.html#characters">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <meta name="fuzzy" content="maxDifference=0-1; totalPixels=0-4000">
+ <meta content="This test checks that 'turn' angle unit is case-insensitive." name="assert">
+
+ <style>
+ div
+ {
+ height: 100px;
+ width: 100px;
+ }
+
+ div#test-overlapping-green
+ {
+ background-color: red;
+ background-image: linear-gradient(0.25tUrN, green, green);
+ }
+
+ div#reference-overlapped-red
+ {
+ background-color: red;
+ bottom: 100px;
+ position: relative;
+ z-index: -1;
+ }
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="test-overlapping-green"></div>
+
+ <div id="reference-overlapped-red"></div>
diff --git a/testing/web-platform/tests/css/css-values/animations/calc-interpolation.html b/testing/web-platform/tests/css/css-values/animations/calc-interpolation.html
new file mode 100644
index 0000000000..40379a13fb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/animations/calc-interpolation.html
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>calc interpolation</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#calc-notation">
+<meta name="assert" content="calc supports animation by computed value">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/interpolation-testcommon.js"></script>
+
+<style>
+.container {
+ position: relative;
+ width: 50px;
+ height: 50px;
+ border: black solid 2px;
+ display: inline-block;
+ margin-left: 10px;
+ margin-right: 10px;
+ background-color: white;
+}
+.target {
+ position: absolute;
+ width: 10px;
+ height: 50px;
+ background-color: black;
+}
+.expected {
+ background-color: green;
+}
+</style>
+
+<body>
+<template id="target-template">
+ <div class="container">
+ <div class="target"></div>
+ </div>
+</template>
+<div class="target" id="inf-target"></div>
+<script>
+const APPROX_INFINITY = (function() {
+ const target = document.getElementById("inf-target");
+ target.style.letterSpacing = "calc(1px * infinity)";
+ const inf = parseFloat(getComputedStyle(target).letterSpacing);
+ target.remove();
+ return inf;
+}());
+
+test_interpolation({
+ property: 'left',
+ from: '0px',
+ to: 'calc(infinity * 1px)',
+ target_names:['CSS Transitions', 'CSS Transitions with transition: all']
+}, [
+ {at: -0.25, expect: `${APPROX_INFINITY * -0.25 }px`},
+ {at: 0, expect: '0px'},
+ {at: 0.25, expect: `${APPROX_INFINITY * 0.25}px`},
+ {at: 0.5, expect: `${APPROX_INFINITY * 0.5}px`},
+ {at: 0.75, expect: `${APPROX_INFINITY * 0.75}px`},
+ {at: 1, expect: `${APPROX_INFINITY}px`},
+ {at: 1.25, expect: `${APPROX_INFINITY * 1.25}px`}
+]);
+
+test_interpolation({
+ property: 'left',
+ from: '0px',
+ to: 'calc(infinity * 1px)',
+ target_names:['CSS Animations', 'Web Animations']
+}, [
+ {at: -0.25, expect: `${-APPROX_INFINITY}px`},
+ {at: 0, expect: `${APPROX_INFINITY}px`},
+ {at: 0.25, expect: `${APPROX_INFINITY}px`},
+ {at: 0.5, expect: `${APPROX_INFINITY}px`},
+ {at: 0.75, expect: `${APPROX_INFINITY}px`},
+ {at: 1, expect: `${APPROX_INFINITY}px`},
+ {at: 1.25, expect: `${APPROX_INFINITY}px`}
+]);
+
+test_interpolation({
+ property: 'left',
+ from: 'calc(50% - 25px)',
+ to: 'calc(100% - 10px)'
+}, [
+ {at: -0.25, expect: '-10px'},
+ {at: 0, expect: '0px'},
+ {at: 0.25, expect: '10px'},
+ {at: 0.5, expect: '20px'},
+ {at: 0.75, expect: '30px'},
+ {at: 1, expect: '40px'},
+ {at: 1.25, expect: '50px'}
+]);
+
+test_interpolation({
+ property: 'text-indent',
+ from: 'calc(50% - 25px)',
+ to: 'calc(100% - 10px)'
+}, [
+ {at: -0.25, expect: 'calc(((50% - 25px) * 1.25) + ((100% - 10px) * -0.25))'},
+ {at: 0, expect: 'calc(50% - 25px)'},
+ {at: 0.25, expect: 'calc(((50% - 25px) * 0.75) + ((100% - 10px) * 0.25))'},
+ {at: 0.5, expect: 'calc(((50% - 25px) * 0.5) + ((100% - 10px) * 0.5))'},
+ {at: 0.75, expect: 'calc(((50% - 25px) * 0.25) + ((100% - 10px) * 0.75))'},
+ {at: 1, expect: 'calc(100% - 10px)'},
+ {at: 1.25, expect: 'calc(((50% - 25px) * -0.25) + ((100% - 10px) * 1.25))'}
+]);
+
+test_interpolation({
+ property: 'text-indent',
+ from: '0em',
+ to: '100px'
+}, [
+ {at: -0.25, expect: '-25px'},
+ {at: 0, expect: '0em'},
+ {at: 0.25, expect: '25px'},
+ {at: 0.5, expect: '50px'},
+ {at: 0.75, expect: '75px'},
+ {at: 1, expect: '100px'},
+ {at: 1.25, expect: '125px'}
+]);
+
+test_interpolation({
+ property: 'text-indent',
+ from: '0%',
+ to: '100px'
+}, [
+ {at: -0.25, expect: 'calc(0% + -25px)'},
+ {at: 0, expect: '0%'},
+ {at: 0.25, expect: 'calc(0% + 25px)'},
+ {at: 0.5, expect: 'calc(0% + 50px)'},
+ {at: 0.75, expect: 'calc(0% + 75px)'},
+ {at: 1, expect: 'calc(0% + 100px)'},
+ {at: 1.25, expect: 'calc(0% + 125px)'}
+]);
+
+</script>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/animations/line-height-lh-transition.html b/testing/web-platform/tests/css/css-values/animations/line-height-lh-transition.html
new file mode 100644
index 0000000000..08c0187495
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/animations/line-height-lh-transition.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>CSS Values and Units Test: line-height transition affecting lh units</title>
+<link rel="help" href="https://www.w3.org/TR/css-values-4/#lh">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #target {
+ width: 20lh;
+ line-height: 10px;
+ transition: line-height 1s;
+ }
+ #target.lh {
+ line-height: 20px;
+ }
+</style>
+<div id="target"></div>
+<script>
+ let t = async_test("lh unit length should change with transitioning line-height");
+
+ t.step(() => {
+ target.offsetTop;
+ target.className = "lh";
+ });
+
+ requestAnimationFrame(() => requestAnimationFrame(() => requestAnimationFrame(() => {
+ t.step(() => {
+ assert_not_equals(getComputedStyle(target).width, "200px");
+ assert_not_equals(getComputedStyle(target).width, "400px");
+ t.done();
+ }, "Transition should be progressing. Not at start/end.");
+ })));
+</script>
diff --git a/testing/web-platform/tests/css/css-values/attr-color-invalid-cast.html b/testing/web-platform/tests/css/css-values/attr-color-invalid-cast.html
new file mode 100644
index 0000000000..d538eebdd9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-color-invalid-cast.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (colors)
+ </title>
+ <meta name="assert" content="
+ Invalid color values in referenced attributes are replaced by the fallback value
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: red; width: 200px; height: 200px; }
+
+ #outer { background: attr(data-test color, green); }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="qqffuutt"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-color-invalid-fallback.html b/testing/web-platform/tests/css/css-values/attr-color-invalid-fallback.html
new file mode 100644
index 0000000000..9e016d1630
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-color-invalid-fallback.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (colors)
+ </title>
+ <meta name="assert" content="
+ When the fallback value of an attr() function is invalid, the delcaration is ignored.
+ " />
+ <meta name="flags" content="invalid">
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; width: 200px; height: 200px; }
+
+ #outer { background: attr(data-test color, qqffuutt); }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="red"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-color-valid.html b/testing/web-platform/tests/css/css-values/attr-color-valid.html
new file mode 100644
index 0000000000..8817e6b94c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-color-valid.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (colors)
+ </title>
+ <meta name="assert" content="
+ The value of the reference attribute is used correctly in the layout when it's a color.
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: red; width: 200px; height: 200px; }
+
+ #outer { background: attr(data-test color); }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="green"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-in-max.html b/testing/web-platform/tests/css/css-values/attr-in-max.html
new file mode 100644
index 0000000000..314ed630b7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-in-max.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Values and Units Test: attr() in max()</title>
+
+ <meta name="assert" content="The attr() function notation is allowed inside a max() notation.">
+ <link rel="author" title="Fuqiao Xue" href="mailto:xfq@w3.org">
+ <link rel="help" href="https://drafts.csswg.org/css-values/#attr-notation">
+ <link rel="help" href="https://drafts.csswg.org/css-values/#calc-notation">
+ <link rel="match" href="reference/200-200-green.html">
+
+ <style>
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: max(attr(data-test length)); height: 200px; }
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="200px"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-invalid-type-001.html b/testing/web-platform/tests/css/css-values/attr-invalid-type-001.html
new file mode 100644
index 0000000000..1f88c37c64
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-invalid-type-001.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (types)
+ </title>
+ <meta name="assert" content="
+ When the type of an attr() function is known and unexpected, the declaration is ignored
+ " />
+ <meta name="flags" content="invalid">
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: 200px; width: attr(data-test color); height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="green"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-invalid-type-002.html b/testing/web-platform/tests/css/css-values/attr-invalid-type-002.html
new file mode 100644
index 0000000000..dbdac8a4ba
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-invalid-type-002.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (types)
+ </title>
+ <meta name="assert" content="
+ When the type of an attr() function is known and unexpected, the declaration is ignored
+ " />
+ <meta name="flags" content="invalid">
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: 200px; width: attr(data-test number); height: 200px; }
+ /* NOTE: while '0' is a valid length AND a valid number, the number type isn't a valid representation of a length. */
+ /* The reason for this is that most numbers aren't valid length */
+ /* ! Spec need some updates to make those assumptions clearly valid (see Tab Atkins for details) */
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="0"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-invalid-type-008.html b/testing/web-platform/tests/css/css-values/attr-invalid-type-008.html
new file mode 100644
index 0000000000..a76be44d76
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-invalid-type-008.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: attr() function with valid and invalid data types</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link href="http://www.w3.org/TR/css3-values/#attr-notation" rel="help">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <meta name="flags" content="invalid">
+ <meta content="When the data type of an attr() function is invalid or when the fallback value does not match the data type, then the attr() function generates an invalid declaration." name="assert">
+
+ <style>
+ div
+ {
+ height: 50px;
+ position: relative;
+ width: 50px;
+ }
+
+ div#valid1
+ {
+ background-color: green;
+ width: attr(attr-test-valid1 length);
+ }
+
+ div#invalid1
+ {
+ background-color: green;
+ width: 100px;
+ width: attr(attr-test-invalid1 number, 0);
+ }
+
+ /*
+ '0' can be both a number and a length. But here,
+ in this sub-test, the width CSS property requires
+ a length type and not a number type. So, the
+ attr() function generates an invalid declaration.
+ */
+
+ div#reference-overlapped-red
+ {
+ background-color: red;
+ bottom: 100px;
+ height: 100px;
+ width: 100px;
+ z-index: -1;
+ }
+
+ div#invalid2
+ {
+ background-color: red;
+ bottom: 100px;
+ width: 0px;
+ width: attr(attr-test-invalid2 length, 100);
+ }
+
+ /*
+ '100' is not a valid length value.
+ So, the attr() function generates an invalid
+ declaration.
+ */
+
+ div#invalid3
+ {
+ background-color: red;
+ bottom: 100px;
+ width: 0px;
+ width: attr(attr-test-invalid3 number, 100px);
+ }
+
+ /*
+ number type is not a valid length value.
+ So, the attr() function generates an invalid
+ declaration.
+ */
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="valid1" attr-test-valid1="100px"></div>
+
+ <div id="invalid1" attr-test-invalid1="foo"></div>
+
+ <div id="reference-overlapped-red"></div>
+
+ <div id="invalid2" attr-test-invalid2="bar"></div>
+
+ <div id="invalid3" attr-test-invalid3="baz"></div>
diff --git a/testing/web-platform/tests/css/css-values/attr-length-invalid-cast.html b/testing/web-platform/tests/css/css-values/attr-length-invalid-cast.html
new file mode 100644
index 0000000000..9308323636
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-length-invalid-cast.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (length)
+ </title>
+ <meta name="assert" content="
+ When the value of referenced attribute isn't a valid length, the fallback value is unsed instead.
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: attr(data-test length, 200px); height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="qqffuutt"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-length-invalid-fallback.html b/testing/web-platform/tests/css/css-values/attr-length-invalid-fallback.html
new file mode 100644
index 0000000000..e68fe7a470
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-length-invalid-fallback.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (length)
+ </title>
+ <meta name="assert" content="
+ When the attr() fallback is an invalid length, the delcaration is correctly ignored.
+ " />
+ <meta name="flags" content="invalid">
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: 200px; width: attr(data-test length, invalid); height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="300px"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-length-valid-zero-nofallback.html b/testing/web-platform/tests/css/css-values/attr-length-valid-zero-nofallback.html
new file mode 100644
index 0000000000..b8a042fd40
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-length-valid-zero-nofallback.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (length)
+ </title>
+ <meta name="assert" content="
+ The value of referenced attribute is used correctly as a length (even if it's 0).
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+ #outer2 { background: red; }
+
+ #outer { width: 200px; height: 200px; }
+ #outer2 { width: 200px; width: attr(data-test length); height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+ <div id="outer2" data-test="0"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-length-valid-zero.html b/testing/web-platform/tests/css/css-values/attr-length-valid-zero.html
new file mode 100644
index 0000000000..fcdebc6fad
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-length-valid-zero.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (length)
+ </title>
+ <meta name="assert" content="
+ The value of referenced attribute is used correctly as a length (even if it's 0).
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+ #outer2 { background: red; }
+
+ #outer { width: 200px; height: 200px; }
+ #outer2 { width: 200px; width: attr(data-test length, 0); height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+ <div id="outer2" data-test="0"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-length-valid.html b/testing/web-platform/tests/css/css-values/attr-length-valid.html
new file mode 100644
index 0000000000..c78258ffe6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-length-valid.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (length)
+ </title>
+ <meta name="assert" content="
+ The value of referenced attribute is used correctly as a length.
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: attr(data-test length); height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="200px"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-px-invalid-cast.html b/testing/web-platform/tests/css/css-values/attr-px-invalid-cast.html
new file mode 100644
index 0000000000..54b43b4076
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-px-invalid-cast.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attributes references (pixels)
+ </title>
+ <meta name="assert" content="
+ When the value of the referenced attribute is not a pixel value, the fallback value is used instead.
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: attr(data-test px, 200px); height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="300px"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-px-invalid-fallback.html b/testing/web-platform/tests/css/css-values/attr-px-invalid-fallback.html
new file mode 100644
index 0000000000..27dfc10240
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-px-invalid-fallback.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (pixels)
+ </title>
+ <meta name="assert" content="
+ When the fallback of a pixel attribute reference is invalid, the declaration is ignored.
+ " />
+ <meta name="flags" content="invalid">
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: 200px; width: attr(data-test px, 300); height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="300"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/attr-px-valid.html b/testing/web-platform/tests/css/css-values/attr-px-valid.html
new file mode 100644
index 0000000000..ec96924a68
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/attr-px-valid.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Attribute references (pixels)
+ </title>
+ <meta name="assert" content="
+ Attribute references for pixel values are replaced correctly at computed time.
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: attr(data-test px); height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer" data-test="200"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-angle-values.html b/testing/web-platform/tests/css/css-values/calc-angle-values.html
new file mode 100644
index 0000000000..699af7a5cd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-angle-values.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: calc() function with angle values</title>
+
+ <!--
+
+ Original test is:
+
+ https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/calc-with-time-angle-and-frequency-values.html
+
+ Issue 917718: [css-values] calc-with-time-angle-and-frequency-values
+ test is highly unreliable, transition-delay testing causes side effects
+ https://bugs.chromium.org/p/chromium/issues/detail?id=917718
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-computed-value">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#angles">
+
+ <meta content="This test checks that additions, subtractions, multiplications and divisions in calc() function when applied to angle units." name="assert">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/css/support/computed-testcommon.js"></script>
+
+ <div id="log"></div>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+ /*
+ In this mega-test of 27 sub-tests, we intentionally
+ set the tolerance precision (epsilon) to a rather big
+ value (0.0001 === 100 millionths). The reason for this
+ is we want to verify if browsers and CSS-capable
+ applications do the right calculations. We do not want
+ to penalize browsers and CSS-capable applications that
+ have modest precision (not capable of a 1 millionth
+ level precision).
+ */
+
+ // testTransformValuesCloseTo(property_name, calcValue, epsilon, expectedValue, description)
+
+ testTransformValuesCloseTo("rotate(calc(45deg + 45deg))", 0.0001, "rotate(90deg)", "addition of 2 angle units: deg plus deg");
+
+ testTransformValuesCloseTo("rotate(calc(45deg + 1rad))", 0.0001, "rotate(102.29578deg)", "addition of 2 angle units: deg plus rad");
+ /*
+ 1 radian == 57.295779513 degrees
+ The original test was using the slightly imprecise rotate(102.3deg)
+ */
+
+ testTransformValuesCloseTo("rotate(calc(20deg + 200grad))", 0.0001, "rotate(200deg)", "addition of 2 angle units: deg plus grad");
+
+ testTransformValuesCloseTo("rotate(calc(200deg + 0.5turn))", 0.0001, "rotate(380deg)", "addition of 2 angle units: deg plus turn");
+
+ testTransformValuesCloseTo("rotate(calc(45rad + 45rad))", 0.0001, "rotate(90rad)", "addition of 2 angle units: rad plus rad");
+
+ testTransformValuesCloseTo("rotate(calc(1rad + 40grad))", 0.0001, "rotate(93.29578deg)", "addition of 2 angle units: rad plus grad");
+
+
+ // 1 radian == 57.295779513 degrees; 40 gradians is 36 degrees.
+
+
+ testTransformValuesCloseTo("rotate(calc(1rad + 0.5turn))", 0.0001, "rotate(237.29578deg)", "addition of 2 angle units: rad plus turn");
+
+ testTransformValuesCloseTo("rotate(calc(45grad + 45grad))", 0.0001, "rotate(90grad)", "addition of 2 angle units: grad plus grad");
+
+ testTransformValuesCloseTo("rotate(calc(10grad + 0.5turn))", 0.0001, "rotate(189deg)", "addition of 2 angle units: grad plus turn");
+
+ // 10 gradians is 9 degrees.
+
+ // subtraction of angle unit
+
+ testTransformValuesCloseTo("rotate(calc(45deg - 15deg))", 0.0001, "rotate(30deg)", "subtraction of angle unit: deg minus deg");
+
+ testTransformValuesCloseTo("rotate(calc(90deg - 1rad))", 0.0001, "rotate(32.70422deg)", "subtraction of angle unit: deg minus rad");
+
+ // 1 radian == 57.295779513 degrees
+
+ testTransformValuesCloseTo("rotate(calc(38deg - 20grad))", 0.0001, "rotate(20deg)", "subtraction of angle unit: deg minus grad");
+
+ testTransformValuesCloseTo("rotate(calc(360deg - 0.5turn))", 0.0001, "rotate(180deg)", "subtraction of angle unit: deg minus turn");
+
+ testTransformValuesCloseTo("rotate(calc(45rad - 15rad))", 0.0001, "rotate(30rad)", "subtraction of angle unit: rad minus rad");
+
+ testTransformValuesCloseTo("rotate(calc(30rad - 10grad))", 0.0001, "rotate(1709.87339deg)", "subtraction of angle unit: rad minus grad");
+
+ // 30 radians is 1718.8733854 degrees ; 10 gradians is 9 degrees.
+
+ testTransformValuesCloseTo("rotate(calc(4rad - 0.1turn))", 0.0001, "rotate(193.18312deg)", "subtraction of angle unit: rad minus turn");
+
+ // 4 radians is 229.183118052 degrees ; 0.1 turn is 36 degrees.
+
+ testTransformValuesCloseTo("rotate(calc(45grad - 15grad))", 0.0001, "rotate(30grad)", "subtraction of angle unit: grad minus grad");
+
+ testTransformValuesCloseTo("rotate(calc(100grad - 0.25turn))", 0.0001, "rotate(0deg)", "subtraction of angle unit: grad minus turn");
+
+
+ // Multiplication of angle unit
+
+ testTransformValuesCloseTo("rotate(calc(45deg * 2))", 0.0001, "rotate(90deg)", "multiplication of angle unit: deg multiplied by int");
+
+ testTransformValuesCloseTo("rotate(calc(2 * 45rad))", 0.0001, "rotate(90rad)", "multiplication of angle unit: int multiplied by rad");
+
+ testTransformValuesCloseTo("rotate(calc(45grad * 2))", 0.0001, "rotate(90grad)", "multiplication of angle unit: grad multiplied by int");
+
+ testTransformValuesCloseTo("rotate(calc(2 * 45turn))", 0.0001, "rotate(90turn)", "multiplication of angle unit: int multiplied by turn");
+
+
+ // Division of angle unit
+
+ testTransformValuesCloseTo( "rotate(calc(90deg / 2))", 0.0001, "rotate(45deg)", "division of angle unit: deg divided by int");
+
+ testTransformValuesCloseTo("rotate(calc(90rad / 2))", 0.0001, "rotate(45rad)", "division of angle unit: rad divided by int");
+
+ testTransformValuesCloseTo("rotate(calc(90grad / 2))", 0.0001, "rotate(45grad)", "division of angle unit: grad divided by int");
+
+ testTransformValuesCloseTo("rotate(calc(90turn / 2))", 0.0001, "rotate(45turn)", "division of angle unit: turn divided by int");
+
+ /*
+
+ deg
+ Degrees. There are 360 degrees in a full circle.
+
+ grad
+ Gradians, also known as "gons" or "grades". There are 400 gradians in a full circle.
+
+ rad
+ Radians. There are 2π radians in a full circle.
+
+ 1rad == 57.295779513°
+ https://www.rapidtables.com/convert/number/radians-to-degrees.html
+
+ π == Math.PI == 3.141592653589793
+
+ turn
+ Turns. There is 1 turn in a full circle.
+
+ */
+
+
+
+ // Testing conversion of angle unit
+
+ testTransformValuesCloseTo("rotate(calc(50grad)", 0.0001, "rotate(45deg)", "conversion of angle unit: grad into deg");
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-image-gradient-1-ref.html b/testing/web-platform/tests/css/css-values/calc-background-image-gradient-1-ref.html
new file mode 100644
index 0000000000..d4b529b964
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-image-gradient-1-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for calc() on background-image gradients</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+p {
+ height: 50px; width: 200px;
+ border: thin solid;
+}
+
+#one { background-image: radial-gradient(circle farthest-side at 150px 20px, red, green); }
+
+</style>
+</head>
+<body>
+<p id="one"></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-image-gradient-1.html b/testing/web-platform/tests/css/css-values/calc-background-image-gradient-1.html
new file mode 100644
index 0000000000..f7d39be8d3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-image-gradient-1.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for calc() on background-image gradients</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-background-image-gradient-1-ref.html">
+<style type="text/css">
+
+p {
+ height: 50px; width: 200px;
+ border: thin solid;
+}
+
+#one { background-image: radial-gradient(circle farthest-side at calc(50px + 50%) calc(100% - 30px), red, green); }
+
+</style>
+</head>
+<body>
+<p id="one"></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-linear-gradient-1-ref.html b/testing/web-platform/tests/css/css-values/calc-background-linear-gradient-1-ref.html
new file mode 100644
index 0000000000..ce415e724c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-linear-gradient-1-ref.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<head>
+ <title>CSS Reference: Support calc() on gradient stop positions</title>
+ <link rel="author" title="Yu-Sian (Thomasy) Liu" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594935">
+<style type="text/css">
+div {
+ width:100px;
+ height:100px;
+ background:red;
+ margin:5px 0 0 5px;
+ float:left;
+}
+div#one {
+ background: linear-gradient(lime 0px, lime 90px, blue 90px, blue 100%);
+}
+div#two {
+ background: linear-gradient(blue 0px ,green 30px ,red 40px ,white 60px , lime 80px);
+}
+div#three {
+ background: linear-gradient(blue 0px ,purple 20px ,red 40px ,blue 60px , lime 80px);
+}
+div#four {
+ background: linear-gradient(blue 0px ,green 30px ,red 40px ,blue 60px , yellow 80px);
+}
+div#five {
+ background: linear-gradient(red 0px ,green 30px);
+}
+</style>
+</head>
+<body>
+<div id="one">1</div>
+<div id="two">2</div>
+<div id="three">3</div>
+<div id="four">4</div>
+<div id="five">5</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-linear-gradient-1.html b/testing/web-platform/tests/css/css-values/calc-background-linear-gradient-1.html
new file mode 100644
index 0000000000..7725083153
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-linear-gradient-1.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<head>
+ <title>CSS Test: Support calc() on gradient stop positions</title>
+ <link rel="author" title="Yu-Sian (Thomasy) Liu" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594935">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-background-linear-gradient-1-ref.html">
+<style type="text/css">
+div {
+ width:100px;
+ height:100px;
+ background:red;
+ margin:5px 0 0 5px;
+ float:left;
+}
+div#one {
+ background: linear-gradient(lime 0px, lime calc(100% - 10px), blue calc(100% - 10px), blue 100%);
+}
+div#two {
+ background: linear-gradient(blue calc(100% - 100px) ,green calc(10% + 20px) ,red 40px ,white calc(100% - 40px) , lime 80px);
+}
+div#three {
+ background: linear-gradient(blue calc(0px) ,purple calc(20%) ,red calc(10px + 10px + 20px) ,blue calc(30% + 30px) , lime calc(180% - 100px));
+}
+div#four {
+ background: linear-gradient(blue calc(0% + 0px) ,green calc(10% + 20px) ,red 40px ,blue calc(200% / 2 - 40px) , yellow 80px);
+}
+div#five {
+ background: linear-gradient(red calc(100% - 100px) ,green calc(10% + 20px));
+}
+
+</style>
+</head>
+<body>
+<div id="one">1</div>
+<div id="two">2</div>
+<div id="three">3</div>
+<div id="four">4</div>
+<div id="five">5</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-position-002.html b/testing/web-platform/tests/css/css-values/calc-background-position-002.html
new file mode 100644
index 0000000000..249cdc3d5e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-position-002.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: computed value of 'background-position' when specified with calc() function</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-computed-value">
+
+ <meta content="This test verifies how 6 calc() functions are computed for 'background-position'." name="assert">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description)
+ {
+
+ test(function()
+ {
+
+ targetElement.style.setProperty(property_name, initial_value);
+
+ /*
+ The purpose of the initial_value is to act as a fallback
+ value in case the calc() function in the specified value
+ fails or in case it generates an invalid value. Since we
+ are running 6 consecutive tests on the same element,
+ then it is necessary to 'reset' its property to an
+ initial value.
+ */
+
+ targetElement.style.setProperty(property_name, specified_value);
+
+ assert_equals(getComputedStyle(targetElement)[property_name], expected_value);
+
+ }, description);
+ }
+
+ /* verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description) */
+
+ verifyComputedStyle("background-position", "initial", "calc(2px + 3px) calc(4px + 5px)", "5px 9px", "testing background-position: calc(2px + 3px) calc(4px + 5px)");
+
+ verifyComputedStyle("background-position", "initial", "calc(18px - 7px) calc(19px - 7px)", "11px 12px", "testing background-position: calc(18px - 7px) calc(19px - 7px)");
+
+ verifyComputedStyle("background-position", "initial", "calc(4 * 5px) calc(6px * 4)", "20px 24px", "testing background-position: calc(4 * 5px) calc(6px * 4)");
+
+ verifyComputedStyle("background-position", "initial", "calc(100px / 4) calc(119px / 7)", "25px 17px", "testing background-position: calc(100px / 4) calc(119px / 7)");
+
+ verifyComputedStyle("background-position", "initial", "calc(6px + 21%) calc(7em + 22%)", "calc(21% + 6px) calc(22% + 112px)", "testing background-position: calc(6px + 21%) calc(7em + 22%)");
+
+ /*
+ "
+ (...) background-position has layout-dependent behavior for
+ percentage values, and thus does not resolve percentages
+ until used-value time. Due to this, background-position
+ computation preserves the percentage in a calc(). (...)
+ "
+ https://www.w3.org/TR/css-values-3/#calc-computed-value
+ */
+
+ verifyComputedStyle("background-position", "initial", "calc(-8px + 23%) calc(-9em + 24%)", "calc(23% - 8px) calc(24% - 144px)", "testing background-position: calc(-8px + 23%) calc(-9em + 24%)");
+
+ /* verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description) */
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-position-003.html b/testing/web-platform/tests/css/css-values/calc-background-position-003.html
new file mode 100644
index 0000000000..a3f5e84862
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-position-003.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: serialization of 'background-position' when specified with calc() function</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#calc-serialize">
+
+ <meta content="This test verifies how 6 calc() functions are serialized for 'background-position'." name="assert">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function verifySerialization(specified_value, serialization_expected, description)
+ {
+
+ test(function()
+ {
+
+ targetElement.style.backgroundPosition = specified_value;
+
+ assert_equals(targetElement.style.backgroundPosition, serialization_expected);
+
+ }, description);
+ }
+
+ /*
+ verifySerialization(specified_value, serialization_expected, description)
+ */
+
+ verifySerialization("calc(2px + 3px) calc(4px + 5px)", "calc(5px) calc(9px)", "testing background-position: calc(2px + 3px) calc(4px + 5px)");
+
+ verifySerialization("calc(18px - 7px) calc(19px - 7px)", "calc(11px) calc(12px)", "testing background-position: calc(18px - 7px) calc(19px - 7px)");
+
+ verifySerialization("calc(4 * 5px) calc(6px * 4)", "calc(20px) calc(24px)", "testing background-position: calc(4 * 5px) calc(6px * 4)");
+
+ verifySerialization("calc(100px / 4) calc(119px / 7)", "calc(25px) calc(17px)", "testing background-position: calc(100px / 4) calc(119px / 7)");
+
+ /*
+ verifySerialization(specified_value, serialization_expected, description)
+ */
+
+ verifySerialization("calc(6px + 21%) calc(7em + 22%)", "calc(21% + 6px) calc(22% + 7em)", "testing background-position: calc(6px + 21%) calc(7em + 22%)");
+
+ verifySerialization("calc(-8px + 23%) calc(-9em + 24%)", "calc(23% - 8px) calc(24% - 9em)", "testing background-position: calc(-8px + 23%) calc(-9em + 24%)");
+
+ /*
+
+ "
+ Sort the terms in the following order:
+
+ The number, if present
+
+ The percentage, if present
+
+ The dimensions, ordered by their units ASCII case-insensitive alphabetically
+ "
+ https://www.w3.org/TR/css-values-4/#math-function-serialize-a-summation
+
+ */
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-position-1-ref.html b/testing/web-platform/tests/css/css-values/calc-background-position-1-ref.html
new file mode 100644
index 0000000000..37c9c68cab
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-position-1-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for calc() on background-position</title>
+ <link rel="author" title="L. David Baron" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594934">
+<style type="text/css">
+
+p {
+ height: 50px; width: 200px;
+ border: thin solid;
+ background-image: url(support/blue-32x32.png);
+ background-repeat: no-repeat;
+}
+
+#one { background-position: 134px -12px }
+#two { background-position: -18px -19px }
+
+</style>
+</head>
+<body>
+<p id="one"></p>
+<p id="two"></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-position-1.html b/testing/web-platform/tests/css/css-values/calc-background-position-1.html
new file mode 100644
index 0000000000..8d3fde5cd8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-position-1.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for calc() on background-position</title>
+ <link rel="author" title="L. David Baron" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594934">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-background-position-1-ref.html">
+<style type="text/css">
+
+p {
+ height: 50px; width: 200px;
+ border: thin solid;
+ background-image: url(support/blue-32x32.png);
+ background-repeat: no-repeat;
+}
+
+#one { background-position: calc(50px + 50%) calc(100% - 30px) }
+#two { background-position: calc(-12.5% + 3px) calc(-10px - 50%) }
+
+</style>
+</head>
+<body>
+<p id="one"></p>
+<p id="two"></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-size-1-ref.html b/testing/web-platform/tests/css/css-values/calc-background-size-1-ref.html
new file mode 100644
index 0000000000..4469f152a3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-size-1-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for calc() on background-size</title>
+ <link rel="author" title="L. David Baron" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594934">
+<style type="text/css">
+
+p {
+ height: 50px; width: 200px;
+ border: thin solid;
+ background-image: url(support/blue-32x32.png);
+ background-repeat: no-repeat;
+}
+
+#one { background-size: 150px 20px; }
+#two { background-image: none }
+
+</style>
+</head>
+<body>
+<p id="one"></p>
+<p id="two"></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-background-size-1.html b/testing/web-platform/tests/css/css-values/calc-background-size-1.html
new file mode 100644
index 0000000000..081ae48357
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-background-size-1.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for calc() on background-size</title>
+ <link rel="author" title="L. David Baron" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594934">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-background-size-1-ref.html">
+<style type="text/css">
+
+p {
+ height: 50px; width: 200px;
+ border: thin solid;
+ background-image: url(support/blue-32x32.png);
+ background-repeat: no-repeat;
+}
+
+#one { background-size: calc(50px + 50%) calc(100% - 30px) }
+#two { background-size: calc(50px + 50%) calc(10px - 50%) }
+
+</style>
+</head>
+<body>
+<p id="one"></p>
+<p id="two"></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-border-radius-1-ref.html b/testing/web-platform/tests/css/css-values/calc-border-radius-1-ref.html
new file mode 100644
index 0000000000..b5b4997f42
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-border-radius-1-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: test for border-radius: calc()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+p {
+ height: 256px;
+ width: 512px;
+ background: blue;
+ border-radius: 21px 6px 12px 29px / 5px 16px 10px 3px;
+}
+
+</style>
+</head>
+<body>
+<p></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-border-radius-1.html b/testing/web-platform/tests/css/css-values/calc-border-radius-1.html
new file mode 100644
index 0000000000..05e98505e5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-border-radius-1.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: test for border-radius: calc()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-border-radius-1-ref.html">
+<style type="text/css">
+
+p {
+ /* We use powers of two here to avoid floating-point issues.
+ See bug 590181. */
+
+ height: 256px;
+ width: 512px;
+ background: blue;
+ border-radius: calc((1/32 * 100%) + 5px)
+ calc((1/64 * 100%) - 2px)
+ calc(10px + (1/256 * 100%))
+ calc((1/16 * 100%) - 3px) /
+ calc((1/32 * 100%) - (1px + (1/128 * 100%)))
+ calc(1/16 * 100%)
+ calc(10px)
+ 3px;
+}
+
+</style>
+</head>
+<body>
+<p></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-catch-divide-by-0.html b/testing/web-platform/tests/css/css-values/calc-catch-divide-by-0.html
new file mode 100644
index 0000000000..ed5dbc90e4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-catch-divide-by-0.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<title>Zero Division: calc() serialization.</title>
+<link rel="author" title="Seokho Song" href="mailto:0xdevssh@gmail.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#calc-type-checking">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id="target"></div>
+<div id="log"></div>
+<script>
+function test_serialization(t,s, {prop="width"}={}) {
+ test_specified_serialization(prop, t, s)
+}
+
+ //TEST CASE |EXPECTED
+var test_map = {
+ "100px * 0 / 0" :"calc(NaN * 1px)",
+ "100px / 0" :"calc(infinity * 1px)",
+ "100px / (0)" :"calc(infinity * 1px)",
+ "100px / (2 - 2)" :"calc(infinity * 1px)",
+ "100px / (2 - (-62 + 64))" :"calc(infinity * 1px)",
+ "100px * (1 / 0)" :"calc(infinity * 1px)",
+ "100px * (1 / (0))" :"calc(infinity * 1px)",
+ "100px * (1 / (2 - 2))" :"calc(infinity * 1px)",
+ "100px * (1 / (2 - (-62 + 64)))" :"calc(infinity * 1px)",
+ "1px * max(1/0, 0)" :"calc(infinity * 1px)",
+ "1px * min(1/0, 0)" :"calc(0px)",
+ "1px * max(0/0, 0)" :"calc(NaN * 1px)",
+ "1px * min(0/0, 0)" :"calc(NaN * 1px)",
+
+ "1px * max(0/0, min(0,10))" :"calc(NaN * 1px)",
+ "1px * clamp(0/0, 0, 10)" :"calc(NaN * 1px)",
+
+ "1px * max(0, min(10, 0/0))" :"calc(NaN * 1px)",
+ "1px * clamp(0, 10, 0/0)" :"calc(NaN * 1px)",
+
+ "1px * max(0, min(0/0, 10))" :"calc(NaN * 1px)",
+ "1px * clamp(0, 0/0, 10)" :"calc(NaN * 1px)",
+
+ "1px * clamp(-1/0, 0, 1/0)" :"calc(0px)",
+ "1px * clamp(-1/0, 1/0, 10)" :"calc(10px)",
+};
+for (var exp in test_map) {
+ test_serialization("calc("+exp+")", test_map[exp])
+}
+
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/calc-ch-ex-lang-ref.html b/testing/web-platform/tests/css/css-values/calc-ch-ex-lang-ref.html
new file mode 100644
index 0000000000..e0ac1ead1e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-ch-ex-lang-ref.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test Reference</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+div {
+ width: calc(1ex + 1ch + 1em);
+ height: calc(1ex + 1ch + 1em);
+ background: green;
+}
+</style>
+<div></div>
diff --git a/testing/web-platform/tests/css/css-values/calc-ch-ex-lang.html b/testing/web-platform/tests/css/css-values/calc-ch-ex-lang.html
new file mode 100644
index 0000000000..eb447475d5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-ch-ex-lang.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: Calc in font-size with ch / ex units across lang changes</title>
+<link rel="help" href="https://drafts.csswg.org/css-values/#ch">
+<link rel="help" href="https://drafts.csswg.org/css-values/#ex">
+<link rel="help" href="https://drafts.csswg.org/css-values/#funcdef-calc">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1431031">
+<link rel="match" href="calc-ch-ex-lang-ref.html">
+<style>
+div[lang] {
+ font-size: calc(1ex + 1ch + 1em);
+}
+</style>
+<div lang="en">
+ <div style="width: 1em; height: 1em; background: green;"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-values/calc-height-block-1-ref.html b/testing/web-platform/tests/css/css-values/calc-height-block-1-ref.html
new file mode 100644
index 0000000000..ffdf9ecbce
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-height-block-1-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for height:calc() or min-height:calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; width: 1px; background: blue; }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div style="height: 50px"></div>
+<div style="height: 50px"></div>
+<div style="height: 75px"></div>
+<div style="height: 45px"></div>
+<div style="height: 40px"></div>
+<div style="height: 30px"></div>
+
+<!-- tests with an auto-height container -->
+<div style="height: 50px"></div>
+<div style="height: 10px"></div>
+<div style="height: 10px"></div>
+<div style="height: 10px"></div>
+<div style="height: 10px"></div>
+<div style="height: 10px"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-height-block-1.html b/testing/web-platform/tests/css/css-values/calc-height-block-1.html
new file mode 100644
index 0000000000..88ad94e2eb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-height-block-1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for height:calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-height-block-1-ref.html">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; height: 100px; width: 1px; }
+body > div > div { background: blue }
+
+/* for auto-height tests */
+body > div > div > div > div { height: 10px }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div><div style="height: calc(50px)"></div></div>
+<div><div style="height: calc(50%)"></div></div>
+<div><div style="height: calc(25px + 50%)"></div></div>
+<div><div style="height: calc(150% / 2 - 30px)"></div></div>
+<div><div style="height: calc(40px + 10% - 20% / 2)"></div></div>
+<div><div style="height: calc(40px - 10%)"></div></div>
+
+<!-- tests with an auto-height container -->
+<div><div><div style="height: calc(50px)"><div></div></div></div></div>
+<div><div><div style="height: calc(50%)"><div></div></div></div></div>
+<div><div><div style="height: calc(25px + 50%)"><div></div></div></div></div>
+<div><div><div style="height: calc(150% / 2 - 30px)"><div></div></div></div></div>
+<div><div><div style="height: calc(40px + 10% - 20% / 2)"><div></div></div></div></div>
+<div><div><div style="height: calc(40px - 10%)"><div></div></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-height-table-1-ref.html b/testing/web-platform/tests/css/css-values/calc-height-table-1-ref.html
new file mode 100644
index 0000000000..5f8ebbe43d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-height-table-1-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test that height:calc() with no percentages has an effect on inner table elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+tbody, tr, td {
+ height: 500px;
+ min-height: 700px;
+ max-height: 2px;
+}
+</style>
+</head>
+<body>
+<table border>
+ <tbody>
+ <tr>
+ <td>cell</td>
+ <td>cell</td>
+ </tr>
+ <tr>
+ <td>cell</td>
+ <td>cell</td>
+ </tr>
+ </tbody>
+</table>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-height-table-1.html b/testing/web-platform/tests/css/css-values/calc-height-table-1.html
new file mode 100644
index 0000000000..faea8dd68d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-height-table-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test that height:calc() with no percentages has an effect on inner table elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-height-table-1-ref.html">
+<style type="text/css">
+tbody, tr, td {
+ height: calc(500px);
+ min-height: calc(700px);
+ max-height: calc(2px);
+}
+</style>
+</head>
+<body>
+<table border>
+ <tbody>
+ <tr>
+ <td>cell</td>
+ <td>cell</td>
+ </tr>
+ <tr>
+ <td>cell</td>
+ <td>cell</td>
+ </tr>
+ </tbody>
+</table>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-in-calc.html b/testing/web-platform/tests/css/css-values/calc-in-calc.html
new file mode 100644
index 0000000000..51a1ae59a0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-in-calc.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Calc() inside calc()
+ </title>
+ <meta name="assert" content="
+ The calc() function notation is allowed inside a calc() notation.
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation"/>
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; overflow: hidden; }
+ #outer { position: absolute; top: 0px; left: 0px; background: green; width: 100%; }
+ #outer { height: calc(calc(100%)); }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-in-color-001.html b/testing/web-platform/tests/css/css-values/calc-in-color-001.html
new file mode 100644
index 0000000000..7db087def7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-in-color-001.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: calc() function in &lt;color&gt;</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-values/#funcdef-calc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="testNode"></div>
+<script>
+const div = document.querySelector("#testNode");
+const TESTS = {
+ // specified -> expected
+ "rgb(calc(0), calc(255 + 0), calc(140 - 139 - 1))": "rgb(0, 255, 0)",
+ "rgba(calc(0%) calc(100%) calc(0%) / calc(10% * 10))": "rgb(0, 255, 0)",
+ "hsl(calc(5deg * (360 / 5)), calc(10% * 10), calc(10% * 10))": "rgb(255, 255, 255)",
+ "hsla(calc(5 * (360 / 5)), calc(10% * 10), calc(10% * 10), calc(1.0))": "rgb(255, 255, 255)"
+}
+
+test(function() {
+ for (let test in TESTS) {
+ div.style.backgroundColor = "";
+ div.style.backgroundColor = test;
+ assert_equals(getComputedStyle(div).backgroundColor, TESTS[test], test);
+ }
+}, "calc() in color functions");
+</script>
diff --git a/testing/web-platform/tests/css/css-values/calc-in-counter-001-ref.xhtml b/testing/web-platform/tests/css/css-values/calc-in-counter-001-ref.xhtml
new file mode 100644
index 0000000000..5614ec09b2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-in-counter-001-ref.xhtml
@@ -0,0 +1,27 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>CSS Test: counter-* properties with a calc() expression</title>
+ <link rel="author" title="Ondřej Žára" href="https://ondras.zarovi.cz/"/>
+ <style type="text/css">
+ body {
+ white-space: nowrap;
+ }
+ </style>
+ </head>
+ <body>
+
+ <p>The following two lines should be the same:</p>
+
+ <div id="test">
+ <span id="a">8</span>
+ <span id="b">10</span>
+ </div>
+
+ <div id="reference">
+ <span>8</span>
+ <span>10</span>
+ </div>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-in-counter-001.xhtml b/testing/web-platform/tests/css/css-values/calc-in-counter-001.xhtml
new file mode 100644
index 0000000000..1a2db83098
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-in-counter-001.xhtml
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>CSS Test: counter-* properties with a calc() expression</title>
+ <link rel="author" title="Ondřej Žára" href="https://ondras.zarovi.cz/"/>
+
+ <link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#counters"/>
+ <link rel="help" href="https://www.w3.org/TR/CSS21/generate.html#propdef-content"/>
+ <link rel="help" href="https://www.w3.org/TR/CSS21/syndata.html#counter"/>
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-notation"/>
+ <link rel="help" href="https://www.w3.org/TR/css-lists-3/#counter-properties"/>
+ <link rel="match" href="calc-in-counter-001-ref.xhtml"/>
+ <style type="text/css">
+
+ body {
+ white-space: nowrap;
+ }
+
+ #a { counter-reset: a calc(3 + 5); }
+ #a::before { content: counter(a); }
+
+ #b { counter-reset: b 0; counter-increment: b calc(4 + 6); }
+ #b::before { content: counter(b); }
+
+ </style>
+ </head>
+ <body>
+
+ <p>The following two lines should be the same:</p>
+
+ <div id="test">
+ <span id="a"></span>
+ <span id="b"></span>
+ </div>
+
+ <div id="reference">
+ <span>8</span>
+ <span>10</span>
+ </div>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-in-font-feature-settings.html b/testing/web-platform/tests/css/css-values/calc-in-font-feature-settings.html
new file mode 100644
index 0000000000..0ce8d7e5c7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-in-font-feature-settings.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: calc() function in font-feature-settings</title>
+<link rel="author" title="Chris Nardi" href="mailto:cnardi@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-values/#funcdef-calc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #test {
+ font-feature-settings: "vert" calc(2);
+ }
+</style>
+<div id="test"></div>
+<script>
+ const div = document.querySelector("#test");
+ // Chrome serializes font-feature-settings with single quotes vs. double quotes
+ // in other browsers, but that's not the issue being tested.
+ const expected = ["'vert' 2", "\"vert\" 2"];
+ test(function() {
+ assert_in_array(getComputedStyle(div).fontFeatureSettings, expected);
+ }, "calc() in font-feature-settings");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/calc-in-max.html b/testing/web-platform/tests/css/css-values/calc-in-max.html
new file mode 100644
index 0000000000..4ae44e4ee9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-in-max.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Values and Units Test: calc() in max()</title>
+
+ <meta name="assert" content="The calc() function notation is allowed inside a max() notation.">
+ <link rel="author" title="Fuqiao Xue" href="mailto:xfq@w3.org">
+ <link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-syntax">
+ <link rel="match" href="reference/all-green.html">
+
+ <style>
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; overflow: hidden; }
+ #outer { position: absolute; top: 0px; left: 0px; background: green; width: 100%; }
+
+ #outer { height: max(calc(100%)); }
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-in-media-queries-001.html b/testing/web-platform/tests/css/css-values/calc-in-media-queries-001.html
new file mode 100644
index 0000000000..af59969635
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-in-media-queries-001.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units and Media Queries Test:
+ Calc function inside media queries
+ </title>
+ <meta name="assert" content="
+ The calc() expression is supported in the min-width media query.
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#width">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html { background: red; }
+ @media (min-width: calc(100px)) {
+ html { background: green; }
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-in-media-queries-002.html b/testing/web-platform/tests/css/css-values/calc-in-media-queries-002.html
new file mode 100644
index 0000000000..b016393a6f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-in-media-queries-002.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units and Media Queries Test:
+ Calc function inside media queries
+ </title>
+ <meta name="assert" content="
+ The calc() expression is supported in the min-width media query properly (=with range clamping).
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-range">
+ <link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#width">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html { background: red; }
+ @media (min-width: calc(-100px)) { /* should clamp to 0px */
+ html { background: green; }
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-in-media-queries-with-mixed-units.html b/testing/web-platform/tests/css/css-values/calc-in-media-queries-with-mixed-units.html
new file mode 100644
index 0000000000..f94df62f28
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-in-media-queries-with-mixed-units.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>test calc with mixed units in media queries</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://www.w3.org/TR/css3-values/#calc-computed-value">
+ </head>
+ <body>
+ <iframe src="./support/mixed-units-01.html" title="px/em" frameborder="0" height="10" width="100"></iframe>
+ <iframe src="./support/mixed-units-02.html" title="vh/em" frameborder="0" height="10" width="100"></iframe>
+ <iframe src="./support/mixed-units-03.html" title="vw/em" frameborder="0" height="10" width="100"></iframe>
+ <iframe src="./support/mixed-units-04.html" title="vw/vh" frameborder="0" height="10" width="100"></iframe>
+ <iframe src="./support/mixed-units-05.html" title="vh/px" frameborder="0" height="10" width="100"></iframe>
+ <iframe src="./support/mixed-units-06.html" title="vw/px" frameborder="0" height="10" width="100"></iframe>
+ <script>
+ for (const frame of document.querySelectorAll("iframe")) {
+ async_test((t) => {
+ frame.addEventListener("load", t.step_func(() => {
+ const box = frame.contentWindow.document.querySelector(".box");
+ const actual = frame.contentWindow.getComputedStyle(box).getPropertyValue("background-color");
+ assert_equals(actual, "rgb(255, 165, 0)");
+ t.done();
+ }));
+ }, `box should be orange if the calc between ${frame.title} in @media was correct`);
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-infinity-nan-computed.html b/testing/web-platform/tests/css/css-values/calc-infinity-nan-computed.html
new file mode 100644
index 0000000000..e10649be6f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-infinity-nan-computed.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Infinity and NaN: calc() computed value.</title>
+<link rel="author" title="Seokho Song" href="mailto:0xdevssh@gmail.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#calc-type-checking">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+const REALLY_LARGE = 1e6;
+const REALLY_LARGE_NEGATIVE = -REALLY_LARGE;
+
+// For <length>
+test_computed_value("width", "calc(NaN * 1px)", "0px");
+test_computed_value("width", "calc(NaN * 1%)", "0px");
+testComputedValueGreaterOrLowerThan("width", "calc(infinity * 1px)", REALLY_LARGE);
+testComputedValueGreaterOrLowerThan("width", "calc(infinity * 1%)", REALLY_LARGE);
+testComputedValueGreaterOrLowerThan("width", "calc(infinity * 1cm)", REALLY_LARGE);
+test_computed_value("width", "calc(NaN * 1rem)", "0px");
+test_computed_value("width", "calc(10.135262721212548pc - 199pt / NaN)", "0px");
+
+test_computed_value("width", "max(15px, NaN * 1px)", "0px");
+test_computed_value("width", "max(NaN * 1px, 15px)", "0px");
+test_computed_value("width", "min(15px, NaN * 1px)", "0px");
+test_computed_value("width", "min(NaN * 1px, 15px)", "0px");
+
+test_computed_value("width", "calc(infinity * 1px - infinity * 1%)", "0px");
+test_computed_value("width", "calc(infinity * 1px + infinity * 1%)", "0px");
+test_computed_value("width", "calc(min(NaN * 1px, infinity * 1px) + max(infinity * 1px, -infinity * 1px))", "0px");
+test_computed_value("width", "calc(infinity * 1px - max(infinity * 1%, 0%))", "0px");
+
+testComputedValueGreaterOrLowerThan("width", "calc(max(infinity * 1px, 10px))", REALLY_LARGE);
+
+testComputedValueGreaterOrLowerThan("margin-left", "calc(-infinity * 1px)", REALLY_LARGE_NEGATIVE);
+testComputedValueGreaterOrLowerThan("margin-left", "calc(min(1px, -infinity * 1%))", REALLY_LARGE_NEGATIVE);
+
+testComputedValueGreaterOrLowerThan("margin-left", "calc(-infinity * 1%)", REALLY_LARGE_NEGATIVE);
+testComputedValueGreaterOrLowerThan("margin-left", "calc(max(10000px, 0px) + min(-infinity * 1px, infinity * 1px))", REALLY_LARGE_NEGATIVE);
+
+testComputedValueGreaterOrLowerThan("margin-left", "calc(-infinity * 1px - infinity * 1px)", REALLY_LARGE_NEGATIVE);
+testComputedValueGreaterOrLowerThan("margin-left", "calc(min(-infinity * 1px, 10px))", REALLY_LARGE_NEGATIVE);
+
+// For <time>
+test_computed_value("animation-duration", "calc(NaN * 1s)", "0s");
+testComputedValueGreaterOrLowerThan("animation-duration", "calc(infinity * 1s)", REALLY_LARGE);
+test_computed_value("animation-duration", "calc(1 / 0 * 1s)", "0s");
+testComputedValueGreaterOrLowerThan("animation-duration", "calc(max(infinity * 1s, 10s)", REALLY_LARGE);
+
+testComputedValueGreaterOrLowerThan("transition-delay", "calc(-infinity* 1s)", REALLY_LARGE_NEGATIVE);
+testComputedValueGreaterOrLowerThan("transition-delay", "calc(max(10000s, 0s) + min(-infinity * 1s, infinity * 1s))", REALLY_LARGE_NEGATIVE);
+testComputedValueGreaterOrLowerThan("transition-delay", "calc(min(-infinity * 1s, 10s))", REALLY_LARGE_NEGATIVE);
+
+// For <angle>
+testTransformValuesCloseTo("rotate(calc(infinity * 1deg))", 0.0001, "rotate(0deg)");
+testTransformValuesCloseTo("rotate(calc(-infinity * 1deg))", 0.0001, "rotate(0deg)");
+testTransformValuesCloseTo("rotate(calc(NaN * 1deg))", 0.0001, "rotate(0deg)");
+
+testTransformValuesCloseTo("rotate(calc(infinity * 1turn))", 0.0001, "rotate(0deg)");
+testTransformValuesCloseTo("rotate(calc(-infinity * 1turn))", 0.0001, "rotate(0deg)");
+testTransformValuesCloseTo("rotate(calc(NaN * 1turn))", 0.0001, "rotate(0deg)");
+
+testTransformValuesCloseTo("rotate(calc(infinity * 1rad))", 0.0001, "rotate(0deg)");
+testTransformValuesCloseTo("rotate(calc(-infinity * 1rad))", 0.0001, "rotate(0deg)");
+testTransformValuesCloseTo("rotate(calc(NaN * 1rad))", 0.0001, "rotate(0deg)");
+
+testTransformValuesCloseTo("rotate(calc(infinity * 1grad))", 0.0001, "rotate(0deg)");
+testTransformValuesCloseTo("rotate(calc(-infinity * 1grad))", 0.0001, "rotate(0deg)");
+testTransformValuesCloseTo("rotate(calc(NaN * 1grad))", 0.0001, "rotate(0deg)");
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-angle.html b/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-angle.html
new file mode 100644
index 0000000000..67feefe512
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-angle.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<title>Infinity and NaN: calc() serialization for length values.</title>
+<link rel="author" title="Seokho Song" href="mailto:0xdevssh@gmail.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#calc-type-checking">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id="target"></div>
+<div id="log"></div>
+<script>
+function test_serialization(t,s, {prop="transform"}={}) {
+ test_specified_serialization(prop, t, s)
+}
+//TEST CASE | EXPECTED
+var test_map = {
+ "1deg * NaN" :"calc(NaN * 1deg)",
+ "1rad * NaN" :"calc(NaN * 1deg)",
+ "1turn * NaN" :"calc(NaN * 1deg)",
+ "1grad * nan" :"calc(NaN * 1deg)",
+ "1deg * infinity / infinity" :"calc(NaN * 1deg)",
+ "1deg * 0 * infinity" :"calc(NaN * 1deg)",
+ "1deg * (infinity + -infinity)" :"calc(NaN * 1deg)",
+ "1deg * (-infinity + infinity)" :"calc(NaN * 1deg)",
+ "1deg * (infinity - infinity)" :"calc(NaN * 1deg)",
+ "1deg * infinity" :"calc(infinity * 1deg)",
+ "1deg * -infinity" :"calc(-infinity * 1deg)",
+ "1deg * iNFinIty" :"calc(infinity * 1deg)",
+ "1deg * (infinity + infinity)" :"calc(infinity * 1deg)",
+ "1deg * (-infinity + -infinity)" :"calc(-infinity * 1deg)",
+ "1deg * 1/infinity" :"calc(0deg)",
+ "1deg * infinity * infinity" :"calc(infinity * 1deg)",
+ "1deg * -infinity * -infinity" :"calc(infinity * 1deg)",
+ "1 * max(INFinity*3deg, 0deg)" :"calc(infinity * 1deg)",
+ "1 * min(inFInity*4deg, 0deg)" :"calc(0deg)",
+ "1 * max(nAn*2deg, 0deg)" :"calc(NaN * 1deg)",
+ "1 * min(nan*3deg, 0deg)" :"calc(NaN * 1deg)",
+ "1 * clamp(-INFINITY*20deg, 0deg, infiniTY*10deg)" :"calc(0deg)",
+
+ "1deg * max(NaN, min(0,10))" :"calc(NaN * 1deg)",
+ "1deg * clamp(NaN, 0, 10)" :"calc(NaN * 1deg)",
+
+ "1deg * max(0, min(10, NaN))" :"calc(NaN * 1deg)",
+ "1deg * clamp(0, 10, NaN)" :"calc(NaN * 1deg)",
+
+ "1deg * max(0, min(NaN, 10))" :"calc(NaN * 1deg)",
+ "1deg * clamp(0, NaN, 10)" :"calc(NaN * 1deg)",
+
+ "1deg * clamp(-Infinity, 0, infinity)" :"calc(0deg)",
+ "1deg * clamp(-inFinity, infinity, 10)" :"calc(10deg)",
+};
+
+for (var exp in test_map) {
+ test_serialization("rotate(calc("+exp+"))", "rotate("+test_map[exp]+")");
+}
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-length.html b/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-length.html
new file mode 100644
index 0000000000..96b4c43e2d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-length.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+<title>Infinity and NaN: calc() serialization for length values.</title>
+<link rel="author" title="Seokho Song" href="mailto:0xdevssh@gmail.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#calc-type-checking">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id="target"></div>
+<div id="log"></div>
+<script>
+function test_serialization(t,s, {prop="width"}={}) {
+ test_specified_serialization(prop, t, s)
+}
+//TEST CASE | EXPECTED
+var test_map = {
+ "1px * NaN" :"calc(NaN * 1px)",
+ "1% * NaN" :"calc(NaN * 1%)",
+ "1in * NaN" :"calc(NaN * 1px)",
+ "1cm * NaN" :"calc(NaN * 1px)",
+ "1mm * NaN" :"calc(NaN * 1px)",
+ "1q * NaN" :"calc(NaN * 1px)",
+ "1pt * NaN" :"calc(NaN * 1px)",
+ "1pc * NaN" :"calc(NaN * 1px)",
+ "1px * nan" :"calc(NaN * 1px)",
+ "1px * infinity / infinity" :"calc(NaN * 1px)",
+ "1px * 0 * infinity" :"calc(NaN * 1px)",
+ "1px * (infinity + -infinity)" :"calc(NaN * 1px)",
+ "1px * (-infinity + infinity)" :"calc(NaN * 1px)",
+ "1px * (infinity - infinity)" :"calc(NaN * 1px)",
+ "1px * infinity" :"calc(infinity * 1px)",
+ "1px * -infinity" :"calc(-infinity * 1px)",
+ "1% * infinity" :"calc(infinity * 1%)",
+ "1% * -infinity" :"calc(-infinity * 1%)",
+ "1px * iNFinIty" :"calc(infinity * 1px)",
+ "1px * (infinity + infinity)" :"calc(infinity * 1px)",
+ "1px * (-infinity + -infinity)" :"calc(-infinity * 1px)",
+ "1px * 1/infinity" :"calc(0px)",
+ "1px * infinity * infinity" :"calc(infinity * 1px)",
+ "1px * -infinity * -infinity" :"calc(infinity * 1px)",
+ "1 * max(INFinity*3px, 0px)" :"calc(infinity * 1px)",
+ "1 * min(inFInity*4px, 0px)" :"calc(0px)",
+ "1 * max(nAn*2px, 0px)" :"calc(NaN * 1px)",
+ "1 * min(nan*3px, 0px)" :"calc(NaN * 1px)",
+ "1 * clamp(-INFINITY*20px, 0px, infiniTY*10px)" :"calc(0px)",
+
+ "1px * max(NaN, min(0,10))" :"calc(NaN * 1px)",
+ "1px * clamp(NaN, 0, 10)" :"calc(NaN * 1px)",
+
+ "1px * max(0, min(10, NaN))" :"calc(NaN * 1px)",
+ "1px * clamp(0, 10, NaN)" :"calc(NaN * 1px)",
+
+ "1px * max(0, min(NaN, 10))" :"calc(NaN * 1px)",
+ "1px * clamp(0, NaN, 10)" :"calc(NaN * 1px)",
+
+ "1px * clamp(-Infinity, 0, infinity)" :"calc(0px)",
+ "1px * clamp(-inFinity, infinity, 10)" :"calc(10px)",
+
+ "1 * min(NaN * 1pt, NaN * 1cm)" :"calc(NaN * 1px)",
+ "1 * max(NaN * 1cm, NaN * 2Q)" :"calc(NaN * 1px)",
+ "1 * min(NaN * 2px, NaN * 4em)" :"min(NaN * 1px, NaN * 1em)",
+ "1 * clamp(NaN * 2em, NaN * 4px, NaN * 8pt)" :"clamp(NaN * 1em, NaN * 1px, NaN * 1px)",
+};
+
+for (var exp in test_map) {
+ test_serialization("calc("+exp+")", test_map[exp]);
+}
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-resolution.html b/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-resolution.html
new file mode 100644
index 0000000000..6548ea7ea7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-resolution.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<title>Infinity and NaN: calc() serialization for time values.</title>
+<link rel="author" title="Seokho Song" href="mailto:0xdevssh@gmail.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#calc-type-checking">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id="target"></div>
+<div id="log"></div>
+<script>
+// There's no css property that takes a raw <resolution>, so we use image-set() to test it.
+function test_serialization(t,s, {prop="backgroundImage"}={}) {
+ test_specified_serialization(prop, t, s)
+}
+//TEST CASE | EXPECTED
+var test_map = {
+ "1x * NaN" :"calc(NaN * 1dppx)",
+ "1x * nan" :"calc(NaN * 1dppx)",
+ "1dppx * NaN" :"calc(NaN * 1dppx)",
+ "1dppx * infinity / infinity" :"calc(NaN * 1dppx)",
+ "1dppx * 0 * infinity" :"calc(NaN * 1dppx)",
+ "1dppx * (infinity + -infinity)" :"calc(NaN * 1dppx)",
+ "1dppx * (-infinity + infinity)" :"calc(NaN * 1dppx)",
+ "1dppx * (infinity - infinity)" :"calc(NaN * 1dppx)",
+ "1dppx * infinity" :"calc(infinity * 1dppx)",
+ "1dppx * -infinity" :"calc(-infinity * 1dppx)",
+ "1dppx * iNFinIty" :"calc(infinity * 1dppx)",
+ "1dppx * (infinity + infinity)" :"calc(infinity * 1dppx)",
+ "1dppx * (-infinity + -infinity)" :"calc(-infinity * 1dppx)",
+ "1dppx * 1/infinity" :"calc(0dppx)",
+ "1dppx * infinity * infinity" :"calc(infinity * 1dppx)",
+ "1dppx * -infinity * -infinity" :"calc(infinity * 1dppx)",
+ "1 * max(INFinity*3dppx, 0dppx)" :"calc(infinity * 1dppx)",
+ "1 * min(inFInity*4dppx, 0dppx)" :"calc(0dppx)",
+ "1 * max(nAn*2dppx, 0dppx)" :"calc(NaN * 1dppx)",
+ "1 * min(nan*3dppx, 0dppx)" :"calc(NaN * 1dppx)",
+ "1 * clamp(-INFINITY*20dppx, 0dppx, infiniTY*10dppx)" :"calc(0dppx)",
+
+ "1dppx * max(NaN, min(0,10))" :"calc(NaN * 1dppx)",
+ "1dppx * clamp(NaN, 0, 10)" :"calc(NaN * 1dppx)",
+
+ "1dppx * max(0, min(10, NaN))" :"calc(NaN * 1dppx)",
+ "1dppx * clamp(0, 10, NaN)" :"calc(NaN * 1dppx)",
+
+ "1dppx * max(0, min(NaN, 10))" :"calc(NaN * 1dppx)",
+ "1dppx * clamp(0, NaN, 10)" :"calc(NaN * 1dppx)",
+
+ "1dppx * clamp(-Infinity, 0, infinity)" :"calc(0dppx)",
+ "1dppx * clamp(-inFinity, infinity, 10)" :"calc(10dppx)",
+};
+
+for (const exp in test_map)
+ test_serialization(`image-set(url("") calc(${exp}))`, `image-set(url("") ${test_map[exp]})`);
+</script>
diff --git a/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-time.html b/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-time.html
new file mode 100644
index 0000000000..2baa890259
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-infinity-nan-serialize-time.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<title>Infinity and NaN: calc() serialization for time values.</title>
+<link rel="author" title="Seokho Song" href="mailto:0xdevssh@gmail.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#calc-type-checking">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id="target"></div>
+<div id="log"></div>
+<script>
+function test_serialization(t,s, {prop="animationDuration"}={}) {
+ test_specified_serialization(prop, t, s)
+}
+//TEST CASE | EXPECTED
+var test_map = {
+ "1s * NaN" :"calc(NaN * 1s)",
+ "1s * nan" :"calc(NaN * 1s)",
+ "1ms * NaN" :"calc(NaN * 1s)",
+ "1s * infinity / infinity" :"calc(NaN * 1s)",
+ "1s * 0 * infinity" :"calc(NaN * 1s)",
+ "1s * (infinity + -infinity)" :"calc(NaN * 1s)",
+ "1s * (-infinity + infinity)" :"calc(NaN * 1s)",
+ "1s * (infinity - infinity)" :"calc(NaN * 1s)",
+ "1s * infinity" :"calc(infinity * 1s)",
+ "1s * -infinity" :"calc(-infinity * 1s)",
+ "1s * iNFinIty" :"calc(infinity * 1s)",
+ "1s * (infinity + infinity)" :"calc(infinity * 1s)",
+ "1s * (-infinity + -infinity)" :"calc(-infinity * 1s)",
+ "1s * 1/infinity" :"calc(0s)",
+ "1s * infinity * infinity" :"calc(infinity * 1s)",
+ "1s * -infinity * -infinity" :"calc(infinity * 1s)",
+ "1 * max(INFinity*3s, 0s)" :"calc(infinity * 1s)",
+ "1 * min(inFInity*4s, 0s)" :"calc(0s)",
+ "1 * max(nAn*2s, 0s)" :"calc(NaN * 1s)",
+ "1 * min(nan*3s, 0s)" :"calc(NaN * 1s)",
+ "1 * clamp(-INFINITY*20s, 0s, infiniTY*10s)" :"calc(0s)",
+
+ "1s * max(NaN, min(0,10))" :"calc(NaN * 1s)",
+ "1s * clamp(NaN, 0, 10)" :"calc(NaN * 1s)",
+
+ "1s * max(0, min(10, NaN))" :"calc(NaN * 1s)",
+ "1s * clamp(0, 10, NaN)" :"calc(NaN * 1s)",
+
+ "1s * max(0, min(NaN, 10))" :"calc(NaN * 1s)",
+ "1s * clamp(0, NaN, 10)" :"calc(NaN * 1s)",
+
+ "1s * clamp(-Infinity, 0, infinity)" :"calc(0s)",
+ "1s * clamp(-inFinity, infinity, 10)" :"calc(10s)",
+};
+
+for (var exp in test_map) {
+ test_serialization("calc("+exp+")", test_map[exp]);
+}
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/calc-integer.html b/testing/web-platform/tests/css/css-values/calc-integer.html
new file mode 100644
index 0000000000..821dac4048
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-integer.html
@@ -0,0 +1,58 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Tests: calc() and division for integers</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-range">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2337">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="test"></div>
+<script>
+const TESTS = [
+ {
+ specified: "calc(2)",
+ computed: "2",
+ description: "Sanity",
+ },
+ {
+ specified: "calc(4 / 2)",
+ computed: "2",
+ description: "Basic division works",
+ },
+ {
+ specified: "calc(1 / 2)",
+ computed: "1",
+ description: "Rounds up if fractional part is >= 0.5",
+ },
+ {
+ specified: "calc(0.5)",
+ computed: "1",
+ description: "Accepts numbers, and rounds",
+ },
+ {
+ specified: "calc(6 / 2.0)",
+ computed: "3",
+ description: "Operation between <integer> and <number> works",
+ },
+ {
+ specified: "calc(1 / 3)",
+ computed: "0",
+ description: "Rounds down if fractional part is < 0.5",
+ },
+ {
+ specified: "calc(calc(1 / 3) * 3)",
+ computed: "1",
+ description: "Only rounds at the end of the conversion",
+ }
+];
+
+const testElement = document.getElementById("test");
+for (const { specified, computed, description } of TESTS) {
+ test(function() {
+ testElement.style.zIndex = "42"; // Just something that we know it's valid and makes tests not rely on order.
+ testElement.style.zIndex = specified;
+ assert_equals(getComputedStyle(testElement).zIndex, computed);
+ }, description);
+}
+</script>
diff --git a/testing/web-platform/tests/css/css-values/calc-invalid-parsing.html b/testing/web-platform/tests/css/css-values/calc-invalid-parsing.html
new file mode 100644
index 0000000000..9e0b09caac
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-invalid-parsing.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>Invalid calc() expressions</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-syntax">
+<script>
+test_invalid_value('transform', 'rotate(calc((0.25turn error)))');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/calc-invalid-range-clamping.html b/testing/web-platform/tests/css/css-values/calc-invalid-range-clamping.html
new file mode 100644
index 0000000000..72ad2a2ff5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-invalid-range-clamping.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Range clamping into calc() expressions
+ </title>
+ <meta name="assert" content="
+ A calc expression can evaluate to a value which is outside the validity range.
+ If it does, this value must be clamped into the range.
+ The declaration must not be ignored.
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ />
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-range"/>
+
+ <link
+ rel="match"
+ href="reference/200-200-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { background: green; width: 200px; height: 200px; }
+ #outer { border-radius: 10px; border-radius: calc(-10px); }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-letter-spacing.html b/testing/web-platform/tests/css/css-values/calc-letter-spacing.html
new file mode 100644
index 0000000000..444785ba14
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-letter-spacing.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: computed value of 'letter-spacing' when specified with calc() function</title>
+
+ <!--
+
+ Original test is:
+
+https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/letter-spacing.html
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css3-values/#calc-computed-value">
+
+ <meta name="flags" content="invalid">
+ <meta content="This test verifies how 6 calc() functions are computed for 'letter-spacing'." name="assert">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ function verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description)
+ {
+
+ var elemTarget = document.getElementById("target");
+
+ test(function()
+ {
+
+ elemTarget.style.setProperty(property_name, initial_value);
+
+ /*
+ In exactly 5 out of the 6 sub-tests, the initial_value will
+ act as a fallback value because the calc() function in the
+ specified value generates an invalid value. Since we are
+ running 6 consecutive tests on the same element, then
+ it is necessary to 'reset' its property to an initial
+ value.
+ */
+
+ elemTarget.style.setProperty(property_name, specified_value);
+
+ assert_equals(getComputedStyle(elemTarget)[property_name], expected_value, specified_value + ' should compute to ' + expected_value);
+
+ }, description);
+ }
+
+ /* verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description) */
+
+ verifyComputedStyle("letter-spacing", "20px", "calc(1 + 1px)", "20px", "testing letter-spacing: calc(1 + 1px)");
+
+ verifyComputedStyle("letter-spacing", "20px", "calc(1 + 100%)", "20px", "testing letter-spacing: calc(1 + 100%)");
+
+ verifyComputedStyle("letter-spacing", "20px", "calc(100%)", "20px", "testing letter-spacing: calc(100%)");
+
+ verifyComputedStyle("letter-spacing", "20px", "calc(10px) bla", "20px", "testing letter-spacing: calc(10px) bla");
+
+ verifyComputedStyle("letter-spacing", "20px", "calc(bla) 10px", "20px", "testing letter-spacing: calc(bla) 10px");
+
+ verifyComputedStyle("letter-spacing", "initial", "calc(10px)", "10px", "testing letter-spacing: calc(10px)");
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-margin-block-1-ref.html b/testing/web-platform/tests/css/css-values/calc-margin-block-1-ref.html
new file mode 100644
index 0000000000..954187dfd7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-margin-block-1-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test of margin-*: calc()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+div { border: medium solid green; width: 500px }
+p { background: yellow }
+
+</style>
+</head>
+<body>
+
+<div><p style="margin: 15px 0 0 0">paragraph with margin</p></div>
+<div><p style="margin: 0 15px 0 0">paragraph with margin</p></div>
+<div><p style="margin: 0 0 15px 0">paragraph with margin</p></div>
+<div><p style="margin: 0 0 0 15px">paragraph with margin</p></div>
+<div><p style="margin: 25px 25px 25px 25px">paragraph with margin</p></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-margin-block-1.html b/testing/web-platform/tests/css/css-values/calc-margin-block-1.html
new file mode 100644
index 0000000000..5b4e061d8a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-margin-block-1.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test of margin-*: calc()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-margin-block-1-ref.html">
+<style type="text/css">
+
+div { border: medium solid green; width: 500px }
+p { background: yellow }
+
+</style>
+</head>
+<body>
+
+<div><p style="margin: calc(10px + 1%) 0 0 0">paragraph with margin</p></div>
+<div><p style="margin: 0 calc(10px + 1%) 0 0">paragraph with margin</p></div>
+<div><p style="margin: 0 0 calc(10px + 1%) 0">paragraph with margin</p></div>
+<div><p style="margin: 0 0 0 calc(10px + 1%)">paragraph with margin</p></div>
+<div><p style="margin: calc(30px - 1%)">paragraph with margin</p></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-max-height-block-1-ref.html b/testing/web-platform/tests/css/css-values/calc-max-height-block-1-ref.html
new file mode 100644
index 0000000000..10719ca547
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-max-height-block-1-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for max-height:calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; width: 1px; background: blue; }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div style="height: 50px"></div>
+<div style="height: 50px"></div>
+<div style="height: 75px"></div>
+<div style="height: 45px"></div>
+<div style="height: 40px"></div>
+<div style="height: 30px"></div>
+
+<!-- tests with an auto-height container -->
+<div style="height: 50px"></div>
+<div style="height: 300px"></div>
+<div style="height: 300px"></div>
+<div style="height: 300px"></div>
+<div style="height: 300px"></div>
+<div style="height: 300px"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-max-height-block-1.html b/testing/web-platform/tests/css/css-values/calc-max-height-block-1.html
new file mode 100644
index 0000000000..48ea8b57e3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-max-height-block-1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for max-height:calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-max-height-block-1-ref.html">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; height: 100px; width: 1px; }
+body > div > div { background: blue }
+
+/* to give the max-height something to restrict */
+span { display: block; height: 300px }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div><div style="max-height: calc(50px)"><span></span></div></div>
+<div><div style="max-height: calc(50%)"><span></span></div></div>
+<div><div style="max-height: calc(25px + 50%)"><span></span></div></div>
+<div><div style="max-height: calc(150% / 2 - 30px)"><span></span></div></div>
+<div><div style="max-height: calc(40px + 10% - 20% / 2)"><span></span></div></div>
+<div><div style="max-height: calc(40px - 10%)"><span></span></div></div>
+
+<!-- tests with an auto-height container -->
+<div><div><div style="max-height: calc(50px)"><span></span></div></div></div>
+<div><div><div style="max-height: calc(50%)"><span></span></div></div></div>
+<div><div><div style="max-height: calc(25px + 50%)"><span></span></div></div></div>
+<div><div><div style="max-height: calc(150% / 2 - 30px)"><span></span></div></div></div>
+<div><div><div style="max-height: calc(40px + 10% - 20% / 2)"><span></span></div></div></div>
+<div><div><div style="max-height: calc(40px - 10%)"><span></span></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-max-width-block-1.html b/testing/web-platform/tests/css/css-values/calc-max-width-block-1.html
new file mode 100644
index 0000000000..9802653272
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-max-width-block-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: max-width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-width-block-1-ref.html">
+<style type="text/css">
+
+body { width: 500px }
+p { background: green; color: white; margin: 1px 0; font-size: 10px; width: 1000px; }
+
+</style>
+</head>
+<body>
+
+<p style="max-width: calc(50% - 3px)">50% - 3px</p>
+<p style="max-width: calc(25% - 3px + 25%)">25% - 3px + 25%</p>
+<p style="max-width: calc(25% - 3px + 12.5% * 2)">25% - 3px + 12.5% * 2</p>
+<p style="max-width: calc(25% - 3px + 12.5%*2)">25% - 3px + 12.5%*2</p>
+<p style="max-width: calc(25% - 3px + 2*12.5%)">25% - 3px + 2*12.5%</p>
+<p style="max-width: calc(25% - 3px + 2 * 12.5%)">25% - 3px + 2 * 12.5%</p>
+<p style="max-width: calc(30% + 20%)">30% + 20%</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-max-width-block-intrinsic-1-ref.html b/testing/web-platform/tests/css/css-values/calc-max-width-block-intrinsic-1-ref.html
new file mode 100644
index 0000000000..6aea315fe4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-max-width-block-intrinsic-1-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: intrinsic width of max-width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+body > div { margin: 0 0 1px 0; background: blue; color: white; height: 5px }
+
+</style>
+</head>
+<body>
+
+<div style="width: 400px"></div>
+<div style="width: 47px"></div>
+<div style="width: 400px"></div>
+<div style="width: 400px"></div>
+<div style="width: 50px"></div>
+<div style="width: 400px"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-max-width-block-intrinsic-1.html b/testing/web-platform/tests/css/css-values/calc-max-width-block-intrinsic-1.html
new file mode 100644
index 0000000000..4aefc481d6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-max-width-block-intrinsic-1.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: intrinsic width of max-width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-max-width-block-intrinsic-1-ref.html">
+<style type="text/css">
+
+body { font-size: 10px }
+body > div { float: left; clear: left;
+ margin: 0 0 1px 0; background: blue; color: white; height: 5px }
+body > div > div { width: 400px }
+body > div > div > div { width: 200px }
+
+</style>
+</head>
+<body>
+
+<div><div style="max-width: calc(50% - 3px)"><div></div></div></div>
+<div><div style="max-width: calc(5em - 3px)"><div></div></div></div>
+<div><div style="max-width: calc(5em - 0%)"><div></div></div></div>
+<div><div style="max-width: calc(50%)"><div></div></div></div>
+<div><div style="max-width: calc(50px)"><div></div></div></div>
+<div><div style="max-width: calc(25% + 25%)"><div></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-min-height-block-1.html b/testing/web-platform/tests/css/css-values/calc-min-height-block-1.html
new file mode 100644
index 0000000000..60ce599afc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-min-height-block-1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for min-height:calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-height-block-1-ref.html">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; height: 100px; width: 1px; }
+body > div > div { background: blue }
+
+/* for auto-height tests */
+body > div > div > div > div { height: 10px }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div><div style="min-height: calc(50px)"></div></div>
+<div><div style="min-height: calc(50%)"></div></div>
+<div><div style="min-height: calc(25px + 50%)"></div></div>
+<div><div style="min-height: calc(150% / 2 - 30px)"></div></div>
+<div><div style="min-height: calc(40px + 10% - 20% / 2)"></div></div>
+<div><div style="min-height: calc(40px - 10%)"></div></div>
+
+<!-- tests with an auto-height container -->
+<div><div><div style="min-height: calc(50px)"><div></div></div></div></div>
+<div><div><div style="min-height: calc(50%)"><div></div></div></div></div>
+<div><div><div style="min-height: calc(25px + 50%)"><div></div></div></div></div>
+<div><div><div style="min-height: calc(150% / 2 - 30px)"><div></div></div></div></div>
+<div><div><div style="min-height: calc(40px + 10% - 20% / 2)"><div></div></div></div></div>
+<div><div><div style="min-height: calc(40px - 10%)"><div></div></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-min-height.html b/testing/web-platform/tests/css/css-values/calc-min-height.html
new file mode 100644
index 0000000000..dd15e70495
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-min-height.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: calc() function in 'min-height' and 'box-sizing: border-box' (complex)</title>
+
+ <!--
+
+ Original test is:
+
+https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/calc-min-height.html
+
+ The original test is related to:
+
+ Issue 580508: Height of content changes after multiple reloads
+ https://bugs.chromium.org/p/chromium/issues/detail?id=580508
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-notation">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <meta name="assert" content="This test checks how 'min-height' with calc(percentage) and 'box-sizing' are handled. The percentage in the calc() is calculated on the content box height of div#container.">
+
+ <style>
+ div#container
+ {
+ border-bottom: transparent solid 100px;
+ border-right: transparent solid 100px;
+ height: 400px;
+ width: 100px;
+ }
+
+ div#item
+ {
+ background-color: red;
+ box-sizing: border-box;
+ height: 50px;
+ min-height: calc(50% - 100px);
+ }
+
+ div#item > div
+ {
+ background-color: green;
+ border-bottom: green solid 34px; /* arbitrary border-bottom-width value */
+ border-top: green solid 12px; /* arbitrary border-top-width value */
+ box-sizing: border-box;
+ height: 17px;
+ min-height: 100%; /* content height should be 100px - 34px - 12px == 54px */
+ overflow-y: visible;
+ /*
+ If the content height of innermost div is taller
+ than 54px, then a green rectangle (not a square)
+ will be created.
+
+ If the content height of innermost div is less
+ than 54px, then an horizontal stripe of red
+ will become visible.
+ */
+ }
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="container">
+
+ <div id="item">
+
+ <div></div>
+
+ </div>
+
+ </div>
diff --git a/testing/web-platform/tests/css/css-values/calc-min-width-block-1.html b/testing/web-platform/tests/css/css-values/calc-min-width-block-1.html
new file mode 100644
index 0000000000..d4de255dd1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-min-width-block-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: min-width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-width-block-1-ref.html">
+<style type="text/css">
+
+body { width: 500px }
+p { background: green; color: white; margin: 1px 0; font-size: 10px; width: 0 }
+
+</style>
+</head>
+<body>
+
+<p style="min-width: calc(50% - 3px)">50% - 3px</p>
+<p style="min-width: calc(25% - 3px + 25%)">25% - 3px + 25%</p>
+<p style="min-width: calc(25% - 3px + 12.5% * 2)">25% - 3px + 12.5% * 2</p>
+<p style="min-width: calc(25% - 3px + 12.5%*2)">25% - 3px + 12.5%*2</p>
+<p style="min-width: calc(25% - 3px + 2*12.5%)">25% - 3px + 2*12.5%</p>
+<p style="min-width: calc(25% - 3px + 2 * 12.5%)">25% - 3px + 2 * 12.5%</p>
+<p style="min-width: calc(30% + 20%)">30% + 20%</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-min-width-block-intrinsic-1-ref.html b/testing/web-platform/tests/css/css-values/calc-min-width-block-intrinsic-1-ref.html
new file mode 100644
index 0000000000..3801928856
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-min-width-block-intrinsic-1-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: intrinsic width of min-width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+body > div { margin: 0 0 1px 0; background: blue; color: white; height: 5px }
+
+</style>
+</head>
+<body>
+
+<div style="width: 1px"></div>
+<div style="width: 47px"></div>
+<div style="width: 1px"></div>
+<div style="width: 1px"></div>
+<div style="width: 50px"></div>
+<div style="width: 1px"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-min-width-block-intrinsic-1.html b/testing/web-platform/tests/css/css-values/calc-min-width-block-intrinsic-1.html
new file mode 100644
index 0000000000..a054c68ab2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-min-width-block-intrinsic-1.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: intrinsic width of min-width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-min-width-block-intrinsic-1-ref.html">
+<style type="text/css">
+
+body { font-size: 10px }
+body > div { float: left; clear: left;
+ margin: 0 0 1px 0; background: blue; color: white; height: 5px }
+body > div > div { width: 1px }
+body > div > div > div { width: 200px }
+
+</style>
+</head>
+<body>
+
+<div><div style="min-width: calc(50% - 3px)"><div></div></div></div>
+<div><div style="min-width: calc(5em - 3px)"><div></div></div></div>
+<div><div style="min-width: calc(5em - 0%)"><div></div></div></div>
+<div><div style="min-width: calc(50%)"><div></div></div></div>
+<div><div style="min-width: calc(50px)"><div></div></div></div>
+<div><div style="min-width: calc(25% + 25%)"><div></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-nesting-002.html b/testing/web-platform/tests/css/css-values/calc-nesting-002.html
new file mode 100644
index 0000000000..269d4e940a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-nesting-002.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: serialization of summation involving nested calc()</title>
+
+ <!--
+
+ This test is an adapted version of the portion of the original test
+
+ https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/calc-nesting.html
+
+ which required using property-parsing-test.js
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#math-function-simplify-an-expression">
+
+ <meta content="This test checks that how a summation involving one or more nested calc() is performed and serialized." name="assert">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function verifySerialization(specified_value, serialization_expected, description)
+ {
+
+ test(function()
+ {
+
+ targetElement.style.left = specified_value;
+
+ assert_equals(targetElement.style.left, serialization_expected);
+
+ }, description);
+ }
+
+ verifySerialization("calc(20px + calc(80px))", "calc(100px)", "testing calc(20px + calc(80px))");
+
+ verifySerialization("calc(calc(100px))", "calc(100px)", "testing calc(calc(100px))");
+
+ verifySerialization("calc(calc(2) * calc(50px)", "calc(100px)", "testing calc(calc(2) * calc(50px)");
+
+ verifySerialization("calc(calc(150px*2/3)", "calc(100px)", "testing calc(calc(150px*2/3)");
+
+ verifySerialization("calc(calc(2 * calc(calc(3)) + 4) * 10px)", "calc(100px)", "testing calc(calc(2 * calc(calc(3)) + 4) * 10px)");
+
+ verifySerialization("calc(50px + calc(40%))", "calc(40% + 50px)", "testing calc(50px + calc(40%))");
+
+ /*
+
+ "
+ Sort the terms in the following order:
+
+ The number, if present
+
+ The percentage, if present
+
+ The dimensions, ordered by their units ASCII case-insensitive alphabetically
+ "
+ https://www.w3.org/TR/css-values-4/#math-function-serialize-a-summation
+
+ */
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-nesting.html b/testing/web-platform/tests/css/css-values/calc-nesting.html
new file mode 100644
index 0000000000..f68d4ae8e9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-nesting.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: nested calc() functions</title>
+
+ <!--
+
+ This test is the first portion of the original test
+
+ https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/calc-nesting.html
+
+ -->
+
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-notation">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+#parent { width: 200px; }
+#div1 { width: calc(calc(50px)); }
+#div2 { width: calc(calc(60%) - 20px); }
+#div3 { width: calc(calc(3 * 25%)); }
+#div4 {
+ --width: calc(10% + 30px);
+ width: calc(2 * var(--width));
+}
+</style>
+<div id=parent>
+ <div id=div1></div>
+ <div id=div2></div>
+ <div id=div3></div>
+ <div id=div4></div>
+</div>
+<script>
+// Tests that require layout
+test(function(){
+ assert_equals(getComputedStyle(div1).width, "50px");
+ assert_equals(getComputedStyle(div2).width, "100px");
+ assert_equals(getComputedStyle(div3).width, "150px");
+ assert_equals(getComputedStyle(div4).width, "100px");
+}, "Nested calcs should work with layout");
+</script>
diff --git a/testing/web-platform/tests/css/css-values/calc-numbers.html b/testing/web-platform/tests/css/css-values/calc-numbers.html
new file mode 100644
index 0000000000..995595b8a3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-numbers.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: computed value of 'tab-size' and 'opacity' when specified with calc() function</title>
+
+ <!--
+
+ Original test is:
+
+https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/calc-numbers.html
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-color-3/#transparency">
+ <link rel="help" href="https://www.w3.org/TR/css-text-3/#tab-size-property">
+ <link rel="help" href="https://www.w3.org/TR/css3-values/#calc-computed-value">
+ <link rel="help" href="https://www.w3.org/TR/css3-values/#calc-range">
+
+ <meta name="flags" content="invalid">
+ <meta content="This test verifies how 11 calc() functions are computed for 'opacity' and 'tab-size'." name="assert">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ function verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description)
+ {
+
+ var elemTarget = document.getElementById("target");
+
+ test(function()
+ {
+
+ elemTarget.style.setProperty(property_name, initial_value);
+
+ /*
+ In exactly 6 out of the 11 sub-tests, the initial_value will
+ act as a fallback value because the specified value generates
+ an invalid value. Since we are running 11 consecutive tests
+ on the same element, then it is necessary to 'reset' its
+ property to an initial value.
+ */
+
+ elemTarget.style.setProperty(property_name, specified_value);
+
+ assert_equals(getComputedStyle(elemTarget)[property_name], expected_value, specified_value + ' should compute to ' + expected_value);
+
+ }, description);
+ }
+
+ /* verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description) */
+
+ verifyComputedStyle("tab-size", "initial", "calc(2 * 3)", "6", "testing tab-size: calc(2 * 3)");
+
+ verifyComputedStyle("tab-size", "12345", "calc(2 * -4)", "0", "testing tab-size: calc(2 * -4)");
+ /*
+ an out-of-range value inside a calc() does not cause
+ the declaration to become invalid. The value resulting
+ from an expression must be clamped to the range
+ allowed in the target context.
+ https://www.w3.org/TR/css-values-3/#calc-range
+ */
+
+ verifyComputedStyle("opacity", "initial", "calc(2 / 4)", "0.5", "testing opacity: calc(2 / 4)");
+
+ verifyComputedStyle("tab-size", "12345", "calc(2 / 4)", "0.5", "testing tab-size: calc(2 / 4)");
+ /*
+ 'tab-size' accepts <number> values.
+ */
+
+ verifyComputedStyle("opacity", "0.9", "calc(2 / 4) * 1px", "0.9", "testing opacity: calc(2 / 4) * 1px");
+
+ verifyComputedStyle("tab-size", "12345", "calc(1 + 1px)", "12345", "testing tab-size: calc(1 + 1px)");
+
+ verifyComputedStyle("tab-size", "12345", "calc(1 + 100%)", "12345", "testing tab-size: calc(1 + 100%)");
+
+ verifyComputedStyle("tab-size", "12345", "calc(100%)", "12345", "testing tab-size: calc(100%)");
+
+ verifyComputedStyle("tab-size", "12345", "calc(10px) bla", "12345", "testing tab-size: calc(10px) bla");
+
+ verifyComputedStyle("tab-size", "12345", "calc(bla) 10px", "12345", "testing tab-size: calc(bla) 10px");
+
+ verifyComputedStyle("tab-size", "initial", "calc(10px)", "10px", "testing tab-size: calc(10px)");
+
+ /* verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description) */
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-absolute-bottom-1.html b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-bottom-1.html
new file mode 100644
index 0000000000..8cdb6b20ea
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-bottom-1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for bottom:calc() on absolutely positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-offsets-absolute-top-1-ref.html">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; margin-top: -90px; height: 100px; margin-bottom: 90px; width: 3px; position: relative }
+div[style] { background: blue; position: absolute; height: 10px; width: 3px }
+div.space { height: 100px }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div><div style="bottom: calc(-50px)"></div></div>
+<div><div style="bottom: calc(-50%)"></div></div>
+<div><div style="bottom: calc(-25px - 50%)"></div></div>
+<div><div style="bottom: calc(-150% / 2 + 30px)"></div></div>
+<div><div style="bottom: calc(-40px - 10% + 20% / 2)"></div></div>
+<div><div style="bottom: calc(-40px + 10%)"></div></div>
+
+<!-- tests with an auto-bottom container -->
+<div><div><div style="bottom: calc(-50px)"></div><div class="space"></div></div></div>
+<div><div><div style="bottom: calc(-50%)"></div><div class="space"></div></div></div>
+<div><div><div style="bottom: calc(-25px - 50%)"></div><div class="space"></div></div></div>
+<div><div><div style="bottom: calc(-150% / 2 + 30px)"></div><div class="space"></div></div></div>
+<div><div><div style="bottom: calc(-40px - 10% + 20% / 2)"></div><div class="space"></div></div></div>
+<div><div><div style="bottom: calc(-40px + 10%)"></div><div class="space"></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-absolute-left-1.html b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-left-1.html
new file mode 100644
index 0000000000..84cc9e4d59
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-left-1.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for left:calc() on absolutely positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-offsets-relative-left-1-ref.html">
+<style type="text/css">
+body { margin: 0 100px; width: 200px }
+body > div { height: 3px; position: relative }
+div[style] { background: blue; position: absolute; height: 3px; width: 100px }
+</style>
+</head>
+<body>
+
+<div><div style="left: calc(50px)"></div></div>
+<div><div style="left: calc(-25%)"></div></div>
+<div><div style="left: calc(25px + 25%)"></div></div>
+<div><div style="left: calc(-75% / 2 + 30px)"></div></div>
+<div><div style="left: calc(40px + 5% - 10% / 2)"></div></div>
+<div><div style="left: calc(5% - 40px)"></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-absolute-right-1.html b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-right-1.html
new file mode 100644
index 0000000000..200ef014c0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-right-1.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for right:calc() on absolutely positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-offsets-relative-left-1-ref.html">
+<style type="text/css">
+body { margin: 0; width: 200px }
+body > div { height: 3px; position: relative }
+div[style] { background: blue; position: absolute; height: 3px; width: 100px }
+</style>
+</head>
+<body>
+
+<div><div style="right: calc(-50px)"></div></div>
+<div><div style="right: calc(25%)"></div></div>
+<div><div style="right: calc(-25px - 25%)"></div></div>
+<div><div style="right: calc(75% / 2 - 30px)"></div></div>
+<div><div style="right: calc(-40px - 5% + 10% / 2)"></div></div>
+<div><div style="right: calc(-5% + 40px)"></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-absolute-top-1-ref.html b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-top-1-ref.html
new file mode 100644
index 0000000000..48062185da
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-top-1-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for top:calc() on absolutely positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; height: 100px; width: 3px; }
+div[style] { background: blue; position: relative; height: 10px; }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div><div style="top: 50px"></div></div>
+<div><div style="top: 50px"></div></div>
+<div><div style="top: 75px"></div></div>
+<div><div style="top: 45px"></div></div>
+<div><div style="top: 40px"></div></div>
+<div><div style="top: 30px"></div></div>
+
+<!-- tests with an auto-top container -->
+<div><div style="top: 50px"></div></div>
+<div><div style="top: 50px"></div></div>
+<div><div style="top: 75px"></div></div>
+<div><div style="top: 45px"></div></div>
+<div><div style="top: 40px"></div></div>
+<div><div style="top: 30px"></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-absolute-top-1.html b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-top-1.html
new file mode 100644
index 0000000000..70a6cd8c70
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-absolute-top-1.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for top:calc() on absolutely positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-offsets-absolute-top-1-ref.html">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; height: 100px; width: 3px; position: relative }
+div[style] { background: blue; position: absolute; height: 10px; width: 3px }
+div.space { height: 100px }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div><div style="top: calc(50px)"></div></div>
+<div><div style="top: calc(50%)"></div></div>
+<div><div style="top: calc(25px + 50%)"></div></div>
+<div><div style="top: calc(150% / 2 - 30px)"></div></div>
+<div><div style="top: calc(40px + 10% - 20% / 2)"></div></div>
+<div><div style="top: calc(40px - 10%)"></div></div>
+
+<!-- tests with an auto-top container -->
+<div><div><div style="top: calc(50px)"></div><div class="space"></div></div></div>
+<div><div><div style="top: calc(50%)"></div><div class="space"></div></div></div>
+<div><div><div style="top: calc(25px + 50%)"></div><div class="space"></div></div></div>
+<div><div><div style="top: calc(150% / 2 - 30px)"></div><div class="space"></div></div></div>
+<div><div><div style="top: calc(40px + 10% - 20% / 2)"></div><div class="space"></div></div></div>
+<div><div><div style="top: calc(40px - 10%)"></div><div class="space"></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-relative-bottom-1.html b/testing/web-platform/tests/css/css-values/calc-offsets-relative-bottom-1.html
new file mode 100644
index 0000000000..afa74a46bd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-relative-bottom-1.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for bottom:calc() on relatively positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-offsets-relative-top-1-ref.html">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; height: 100px; width: 3px; }
+div[style] { background: blue; position: relative; height: 10px; }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div><div style="bottom: calc(-50px)"></div></div>
+<div><div style="bottom: calc(-50%)"></div></div>
+<div><div style="bottom: calc(-25px - 50%)"></div></div>
+<div><div style="bottom: calc(-150% / 2 + 30px)"></div></div>
+<div><div style="bottom: calc(-40px - 10% + 20% / 2)"></div></div>
+<div><div style="bottom: calc(-40px + 10%)"></div></div>
+
+<!-- tests with an auto-top container -->
+<div><div><div style="bottom: calc(-50px)"></div></div></div>
+<div><div><div style="bottom: calc(-50%)"></div></div></div>
+<div><div><div style="bottom: calc(-25px - 50%)"></div></div></div>
+<div><div><div style="bottom: calc(-150% / 2 + 30px)"></div></div></div>
+<div><div><div style="bottom: calc(-40px - 10% + 20% / 2)"></div></div></div>
+<div><div><div style="bottom: calc(-40px + 10%)"></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-relative-left-1-ref.html b/testing/web-platform/tests/css/css-values/calc-offsets-relative-left-1-ref.html
new file mode 100644
index 0000000000..b9a2a4b914
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-relative-left-1-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for left:calc() on relatively positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+body { margin: 0 100px; width: 100px }
+div[style] { background: blue; position: relative; height: 3px; }
+</style>
+</head>
+<body>
+
+<div style="left: 50px"></div>
+<div style="left: -50px"></div>
+<div style="left: 75px"></div>
+<div style="left: -45px"></div>
+<div style="left: 40px"></div>
+<div style="left: -30px"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-relative-left-1.html b/testing/web-platform/tests/css/css-values/calc-offsets-relative-left-1.html
new file mode 100644
index 0000000000..99fcdd983e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-relative-left-1.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for left:calc() on relatively positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-offsets-relative-left-1-ref.html">
+<style type="text/css">
+body { margin: 0 100px; width: 100px }
+div[style] { background: blue; position: relative; height: 3px; }
+</style>
+</head>
+<body>
+
+<div style="left: calc(50px)"></div>
+<div style="left: calc(-50%)"></div>
+<div style="left: calc(25px + 50%)"></div>
+<div style="left: calc(-150% / 2 + 30px)"></div>
+<div style="left: calc(40px + 10% - 20% / 2)"></div>
+<div style="left: calc(10% - 40px)"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-relative-right-1.html b/testing/web-platform/tests/css/css-values/calc-offsets-relative-right-1.html
new file mode 100644
index 0000000000..1f28cf182e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-relative-right-1.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for right:calc() on relatively positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-offsets-relative-left-1-ref.html">
+<style type="text/css">
+body { margin: 0 100px; width: 100px }
+div[style] { background: blue; position: relative; height: 3px; }
+</style>
+</head>
+<body>
+
+<div style="right: calc(-50px)"></div>
+<div style="right: calc(50%)"></div>
+<div style="right: calc(-25px - 50%)"></div>
+<div style="right: calc(150% / 2 - 30px)"></div>
+<div style="right: calc(-40px - 10% + 20% / 2)"></div>
+<div style="right: calc(-10% + 40px)"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-relative-top-1-ref.html b/testing/web-platform/tests/css/css-values/calc-offsets-relative-top-1-ref.html
new file mode 100644
index 0000000000..d46152317d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-relative-top-1-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for top:calc() on relatively positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; height: 100px; width: 3px; }
+div[style] { background: blue; position: relative; height: 10px; }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div><div style="top: 50px"></div></div>
+<div><div style="top: 50px"></div></div>
+<div><div style="top: 75px"></div></div>
+<div><div style="top: 45px"></div></div>
+<div><div style="top: 40px"></div></div>
+<div><div style="top: 30px"></div></div>
+
+<!-- tests with an auto-top container -->
+<div><div style="top: 50px"></div></div>
+<div><div style="top: 0px"></div></div>
+<div><div style="top: 0px"></div></div>
+<div><div style="top: 0px"></div></div>
+<div><div style="top: 0px"></div></div>
+<div><div style="top: 0px"></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-offsets-relative-top-1.html b/testing/web-platform/tests/css/css-values/calc-offsets-relative-top-1.html
new file mode 100644
index 0000000000..938616b8a5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-offsets-relative-top-1.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for top:calc() on relatively positioned elements</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-offsets-relative-top-1-ref.html">
+<style type="text/css">
+body { margin: 0 }
+body > div { float: left; height: 100px; width: 3px; }
+div[style] { background: blue; position: relative; height: 10px; }
+</style>
+</head>
+<body>
+
+<!-- tests with a fixed-height container -->
+<div><div style="top: calc(50px)"></div></div>
+<div><div style="top: calc(50%)"></div></div>
+<div><div style="top: calc(25px + 50%)"></div></div>
+<div><div style="top: calc(150% / 2 - 30px)"></div></div>
+<div><div style="top: calc(40px + 10% - 20% / 2)"></div></div>
+<div><div style="top: calc(40px - 10%)"></div></div>
+
+<!-- tests with an auto-top container -->
+<div><div><div style="top: calc(50px)"></div></div></div>
+<div><div><div style="top: calc(50%)"></div></div></div>
+<div><div><div style="top: calc(25px + 50%)"></div></div></div>
+<div><div><div style="top: calc(150% / 2 - 30px)"></div></div></div>
+<div><div><div style="top: calc(40px + 10% - 20% / 2)"></div></div></div>
+<div><div><div style="top: calc(40px - 10%)"></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-padding-block-1-ref.html b/testing/web-platform/tests/css/css-values/calc-padding-block-1-ref.html
new file mode 100644
index 0000000000..400e5b103e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-padding-block-1-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test of padding-*: calc()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+body { width: 500px }
+div { border: medium solid green }
+p { background: yellow; margin: 0 }
+
+</style>
+</head>
+<body>
+
+<div style="padding: 15px 0 0 0"><p>paragraph with padding</p></div>
+<div style="padding: 0 15px 0 0"><p>paragraph with padding</p></div>
+<div style="padding: 0 0 15px 0"><p>paragraph with padding</p></div>
+<div style="padding: 0 0 0 15px"><p>paragraph with padding</p></div>
+<div style="padding: 25px 25px 25px 25px"><p>paragraph with padding</p></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-padding-block-1.html b/testing/web-platform/tests/css/css-values/calc-padding-block-1.html
new file mode 100644
index 0000000000..c1bb97eaf6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-padding-block-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test of padding-*: calc()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-padding-block-1-ref.html">
+<style type="text/css">
+
+body { width: 500px }
+div { border: medium solid green }
+p { background: yellow; margin: 0 }
+
+</style>
+</head>
+<body>
+
+<div style="padding: calc(10px + 1%) 0 0 0"><p>paragraph with padding</p></div>
+<div style="padding: 0 calc(10px + 1%) 0 0"><p>paragraph with padding</p></div>
+<div style="padding: 0 0 calc(10px + 1%) 0"><p>paragraph with padding</p></div>
+<div style="padding: 0 0 0 calc(10px + 1%)"><p>paragraph with padding</p></div>
+<div style="padding: calc(30px - 1%)"><p>paragraph with padding</p></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-parenthesis-stack.html b/testing/web-platform/tests/css/css-values/calc-parenthesis-stack.html
new file mode 100644
index 0000000000..d8dbafb3f7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-parenthesis-stack.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ 32 nested pairs of parentheses inside calc()
+ </title>
+ <meta name="assert" content="
+ This test checks the support for the minimum required number of 32 nested pairs of parentheses inside a calc() function.
+ " />
+
+ <!--
+ More info:
+ [css-values] Limit nested pairs of parentheses in calc to 32
+ https://github.com/w3c/csswg-drafts/issues/3462
+ -->
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation"/>
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; overflow: hidden; }
+ #outer { position: absolute; top: 0px; left: 0px; background: green; width: 100%; }
+ #outer { height: calc((((((((((((((((((((((((((((((((100%)))))))))))))))))))))))))))))))); }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-positive-fraction-001.html b/testing/web-platform/tests/css/css-values/calc-positive-fraction-001.html
new file mode 100644
index 0000000000..89d1798a7b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-positive-fraction-001.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Test: calc() with positive fraction halfway between adjacent integers</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#combine-integers">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <style>
+ div
+ {
+ height: 100px;
+ position: absolute;
+ width: 100px;
+ }
+
+ div#red-overlapped
+ {
+ background-color: red;
+ z-index: 2;
+ }
+
+ div#green-overlapping
+ {
+ background-color: green;
+ z-index: calc(3 / 2);
+ /*
+ should resolve to 'z-index: 2' since "values
+ halfway between adjacent integers rounded
+ towards positive infinity" and since
+ div#green-overlapping is last in document
+ tree order, then it should overlap
+ div#red-overlapped
+ */
+ }
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="red-overlapped"></div>
+
+ <div id="green-overlapping"></div>
diff --git a/testing/web-platform/tests/css/css-values/calc-rem-lang-ref.html b/testing/web-platform/tests/css/css-values/calc-rem-lang-ref.html
new file mode 100644
index 0000000000..a0f6add684
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-rem-lang-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test Reference</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<p>You should see a green box twice-the-initial-font-size wide.</p>
+<div style="width: 2em; height: 2em; background: green;"></div>
diff --git a/testing/web-platform/tests/css/css-values/calc-rem-lang.html b/testing/web-platform/tests/css/css-values/calc-rem-lang.html
new file mode 100644
index 0000000000..3994efc003
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-rem-lang.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html lang="en"><!-- The lang is important! -->
+<meta charset="utf-8">
+<title>CSS Test: Calc with rem and relative units on the root element</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-values/#rem">
+<link rel="help" href="https://drafts.csswg.org/css-values/#funcdef-calc">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1431031">
+<link rel="match" href="calc-rem-lang-ref.html">
+<style>
+ html {
+ font-size: calc(1rem + 1em);
+ }
+</style>
+<p style="font-size: initial">You should see a green box twice-the-initial-font-size wide.</p>
+<div style="width: 1em; height: 1em; background: green;"></div>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-rgb-percent-001.html b/testing/web-platform/tests/css/css-values/calc-rgb-percent-001.html
new file mode 100644
index 0000000000..e7166fbf42
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-rgb-percent-001.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values Test: computed value of rgb() with calc(percentage)</title>
+
+ <!--
+
+ Original code is from Yves Lafon
+
+ Re: [css3-values] percentage in calc() and attr()
+ https://lists.w3.org/Archives/Public/www-style/2016May/0028.html
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-notation">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <style>
+ div#target
+ {
+ background-color: rgb(calc(5% + 15%), calc(40% / 2), calc(5% * 4));
+ height: 100px;
+ }
+ </style>
+
+ <div id="target"></div>
+
+ <script>
+ test(function()
+ {
+ assert_equals(getComputedStyle(document.getElementById("target")).backgroundColor, "rgb(51, 51, 51)");
+ }, "testing rgb(calc(5% + 15%), calc(40% / 2), calc(5% * 4))");
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-rounding-001.html b/testing/web-platform/tests/css/css-values/calc-rounding-001.html
new file mode 100644
index 0000000000..dfd03a6953
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-rounding-001.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<meta charset="utf-8">
+<title>CSS Test: calc rounding doesn't accumulate a lot of error.</title>
+<link rel="author" href="mailto:mats@mozilla.com" title="Mats Palmgren">
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1323735">
+<link rel="help" href="https://drafts.csswg.org/css-values/#funcdef-calc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+body {
+ background: #f3f5f6;
+}
+
+div {
+ font-size: 15px;
+ width: 401px;
+ margin: 20px;
+ background: #fff;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+b {
+ height: 50px;
+ background: red;
+ width: calc((100% - 4.5em) / 4); /* .5em gutters */
+}
+
+b:not(:last-child) {
+ margin-right: 1.5em;
+}
+</style>
+<div><b></b><b></b><b></b><b></b></div>
+<script>
+ test(function() {
+ assert_equals(document.querySelector("div").offsetHeight, 50);
+ }, "calc() doesn't accumulate much error that makes flex items overflow");
+</script>
diff --git a/testing/web-platform/tests/css/css-values/calc-rounds-to-integer.html b/testing/web-platform/tests/css/css-values/calc-rounds-to-integer.html
new file mode 100644
index 0000000000..80589785c3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-rounds-to-integer.html
@@ -0,0 +1,120 @@
+<!doctype html>
+<title>Calc rounds to integer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<link rel=author title="Tab Atkins-Bittner" href="https://www.xanthir.com/contact/">
+<link rel="help" href="https://drafts.csswg.org/css-values/#calc-range">
+<link rel="help" href="https://drafts.csswg.org/css-easing/#funcdef-step-easing-function-steps">
+<link rel="help" href="https://drafts.csswg.org/css-multicol-2/#column-span">
+<link rel="help" href="https://drafts.csswg.org/css-lists/#propdef-counter-reset">
+<link rel="help" href="https://drafts.csswg.org/css-lists/#propdef-counter-increment">
+<link rel="help" href="https://drafts.csswg.org/css-lists/#propdef-counter-set">
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-feature-settings-prop">
+<link rel="help" href="https://drafts.csswg.org/css-grid/#propdef-grid-template-rows">
+<link rel="help" href="https://drafts.csswg.org/css-grid/#propdef-grid-row">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#propdef-hyphenate-limit-chars">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#propdef-hyphenate-limit-lines">
+<link rel="help" href="https://drafts.csswg.org/css-inline-3/#propdef-initial-letter">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#propdef-max-lines">
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#propdef-order">
+<link rel="help" href="https://drafts.csswg.org/css-break-4/#propdef-orphans">
+<link rel="help" href="https://drafts.csswg.org/css-writing-modes-4/#propdef-text-combine-upright">
+<link rel="help" href="https://drafts.csswg.org/css-break-4/#propdef-widows">
+<link rel="help" href="https://drafts.csswg.org/css2/#propdef-z-index">
+<!--
+ Verifying that, per V&U, a calc() that results in a non-integer value
+ gets rounded to the nearest integer
+ when used in a place that requires <integer> specifically.
+ This tests both straight-up decimal-point values,
+ and scinot, which is defined to parse as <number-token>.
+-->
+<body>
+
+<script>
+
+runTests("animation-timing-function", "steps(xxx)");
+runTests("column-span");
+runTests("counter-increment", "foo xxx");
+runTests("counter-reset", "foo xxx");
+runTests("counter-set", "foo xxx");
+runTests("font-feature-settings", '"fooo" xxx');
+runTests("grid-row");
+runTests("grid-template-rows", "repeat(xxx, 10px)");
+runTests("hyphenate-limit-chars");
+runTests("hyphenate-limit-lines");
+runTests("initial-letter", "1.1 xxx");
+runTests("max-lines");
+runTests("order");
+runTests("orphans");
+runTests("text-combine-upright", "digits xxx");
+runTests("transition-timing-function", "steps(xxx)");
+runTests("widows");
+runTests("z-index");
+
+
+function runTests(prop, valPattern="xxx") {
+ const el = document.body;
+
+ // Don't spuriously fail bc the prop or val isn't supported.
+ if(!verifySupport(el, prop, valPattern)) return;
+
+ const validValues = [
+ "10",
+ "calc(10)",
+ "calc(10.1)",
+ "calc(1e1)",
+ "calc(1.1e1)",
+ ];
+ const invalidValues = [
+ "1e1",
+ "1.1e1",
+ "10.1",
+ ];
+ for(let testVal of validValues) {
+ testInt(el, prop, testVal, valPattern);
+ }
+ for(let testVal of invalidValues) {
+ testIntInvalid(el, prop, testVal, valPattern);
+ }
+}
+
+function verifySupport(el, prop, valPattern) {
+ let testVal = "10";
+ if(valPattern !== undefined) {
+ testVal = valPattern.replace("xxx", testVal);
+ }
+ el.removeAttribute("style");
+ const nullVal = getComputedStyle(el)[prop];
+ el.style.setProperty(prop, testVal);
+ return getComputedStyle(el)[prop] != nullVal;
+}
+
+function testInt(el, prop, testVal, valPattern) {
+ // to avoid needing to specify serialization,
+ // just test whether it parses at all
+ if(valPattern !== undefined) {
+ testVal = valPattern.replace("xxx", testVal);
+ }
+ test(()=>{
+ el.removeAttribute("style");
+ const nullVal = getComputedStyle(el)[prop];
+ el.style.setProperty(prop, testVal);
+ assert_not_equals(getComputedStyle(el)[prop], nullVal);
+ }, `${prop} should accept "${testVal}"`)
+}
+
+function testIntInvalid(el, prop, testVal, valPattern) {
+ // similarly, just verify it doesn't parse at all
+ if(valPattern !== undefined) {
+ testVal = valPattern.replace("xxx", testVal);
+ }
+ test(()=>{
+ el.removeAttribute("style");
+ const nullVal = getComputedStyle(el)[prop];
+ el.style.setProperty(prop, testVal);
+ assert_equals(getComputedStyle(el)[prop], nullVal);
+ }, `${prop} should not accept "${testVal}"`)
+}
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/calc-serialization-002.html b/testing/web-platform/tests/css/css-values/calc-serialization-002.html
new file mode 100644
index 0000000000..79159480b9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-serialization-002.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units: serialization of calc() specified values: 19 arithmetical operations (complex)</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#calc-serialize">
+
+ <meta content="" name="flags">
+ <meta content="This test verifies how 19 arithmetical operations of mixed length units in calc() specified values are serialized. Absolute length units (cm, in, mm, pc, pt, q, px), font-relative length units (ex, em, rem), viewport-percentage length units (vh, vmax, vmin, vw) and percentage units are tested. 12 additions, 6 substractions and 1 division are tested." name="assert">
+
+ <!--
+
+ Issue 1050968: CSS calc and other math function serialization doesn't follow the spec
+ https://bugs.chromium.org/p/chromium/issues/detail?id=1050968
+
+ -->
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function verifySerialization(specified_value, serialization_expected, description)
+ {
+
+ test(function()
+ {
+
+ targetElement.style.height = specified_value;
+
+ assert_equals(targetElement.style.height, serialization_expected);
+
+ }, description);
+ }
+
+ /*
+
+ "
+
+ If nodes contains a number, remove it from nodes and append it to ret.
+
+ If nodes contains a percentage, remove it from nodes and append it to ret.
+
+ If nodes contains any dimensions, remove them from nodes, sort them by their units, ordered ASCII case-insensitively, and append them to ret.
+
+ If nodes still contains any items, append them to ret in the same order.
+
+ "
+ https://www.w3.org/TR/css-values-4/#calc-serialize
+
+ */
+
+ /* 12 Additions */
+
+ verifySerialization("calc(1vh + 2px + 3%)", "calc(3% + 2px + 1vh)", "testing calc(1vh + 2px + 3%)");
+
+ verifySerialization("calc(4px + 1vh)", "calc(4px + 1vh)", "testing calc(4px + 1vh)");
+
+ verifySerialization("calc(5px + 6em + 1vh)", "calc(6em + 5px + 1vh)", "testing calc(5px + 6em + 1vh)");
+
+ verifySerialization("calc(-8px + 9em + 1vh)", "calc(9em - 8px + 1vh)", "testing calc(-8px + 9em + 1vh)");
+
+ verifySerialization("calc(1pc + 1in + 1vh + 10%)", "calc(10% + 112px + 1vh)", "testing calc(1pc + 1in + 1vh + 10%)");
+
+ verifySerialization("calc(25.4q + 1vh + 12%)", "calc(12% + 24px + 1vh)", "testing calc(25.4q + 1vh + 12%)");
+
+ verifySerialization("calc(1em + 1.27cm + 13% + 3em)", "calc(13% + 4em + 48px)", "testing calc(1em + 1.27cm + 13% + 3em)");
+
+ /* verifySerialization(specified_value, serialization_expected, description) */
+
+ verifySerialization("calc(15vw + 16vmin - 17vh)", "calc(-17vh + 16vmin + 15vw)", "testing calc(15vw + 16vmin - 17vh)");
+
+ verifySerialization("calc(9pt + calc(9rem + 10px))", "calc(22px + 9rem)", "testing calc(9pt + calc(9rem + 10px))");
+
+ verifySerialization("calc(5pt + 5em + 4pt + 3em)", "calc(8em + 12px)", "testing calc(5pt + 5em + 4pt + 3em)");
+
+ verifySerialization("calc(4vmin + 0pt + 3pc)", "calc(48px + 4vmin)", "testing calc(4vmin + 0pt + 3pc)");
+
+ verifySerialization("calc(4vmin + 0pt)", "calc(0px + 4vmin)", "testing calc(4vmin + 0pt)");
+
+ /*
+
+ More info on the calc(4vmin + 0pt) sub-test:
+ https://github.com/web-platform-tests/wpt/pull/38245#issuecomment-1464215777
+ Date: March 10th 2023
+
+ */
+
+ /* 6 Substractions */
+
+
+ verifySerialization("calc(100% - 100% + 1em)", "calc(0% + 1em)", "testing calc(100% - 100% + 1em)");
+
+ verifySerialization("calc(100% + 1em - 100%)", "calc(0% + 1em)", "testing calc(100% + 1em - 100%)");
+
+ verifySerialization("calc(1vh - 7px)", "calc(-7px + 1vh)", "testing calc(1vh - 7px)");
+
+ verifySerialization("calc(5ex - 9ex)", "calc(-4ex)", "testing calc(5ex - 9ex)");
+
+ /*
+
+ An out-of-range value inside calc() is not syntactically invalid.
+ Inside a calc() function, the resulting summation value can be
+ out of range and can be serialized.
+
+ */
+
+ verifySerialization("calc(-80px + 25.4mm)", "calc(16px)", "testing calc(-80px + 25.4mm)");
+
+ /* verifySerialization(specified_value, serialization_expected, description) */
+
+ verifySerialization("calc(1vmin - 14%)", "calc(-14% + 1vmin)", "testing calc(1vmin - 14%)");
+
+
+ /* 1 Multiplication and division */
+
+
+ verifySerialization("calc(4 * 3px + 4pc / 8)", "calc(20px)", "testing calc(4 * 3px + 4pc / 8)");
+
+ /*
+ This calc(4 * 3px + 4pc / 8) test is on purpose last. We want the
+ div#target to occupy 20px and to not cause document box height
+ to be unneedlessly tall.
+ */
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-serialization.html b/testing/web-platform/tests/css/css-values/calc-serialization.html
new file mode 100644
index 0000000000..f92de7338d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-serialization.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Values and Units: calc() serialization.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#calc-serialize">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/1731">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="content"></div>
+<script>
+test(function() {
+ // specified -> expected
+ var values = {
+ "calc(10px + 1vmin + 10%)": "calc(10% + 10px + 1vmin)",
+ "calc(10px + 1vmin)": "calc(10px + 1vmin)",
+ "calc(10px + 1em)": "calc(1em + 10px)",
+ "calc(1vmin - 10px)": "calc(-10px + 1vmin)",
+ "calc(-10px + 1em)": "calc(1em - 10px)",
+ "calc(-10px)": "calc(-10px)",
+ };
+
+ var content = document.getElementById("content");
+
+ for (var prop in values) {
+ content.style.width = prop;
+ assert_equals(content.style.width, values[prop], "Serialization of " + prop);
+ }
+}, "calc() serialization")
+</script>
diff --git a/testing/web-platform/tests/css/css-values/calc-text-indent-1-ref.html b/testing/web-platform/tests/css/css-values/calc-text-indent-1-ref.html
new file mode 100644
index 0000000000..71c0b48d6e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-text-indent-1-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: text-indent: calc()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+body { width: 500px }
+p { font-size: 10px }
+
+</style>
+</head>
+<body>
+
+<p style="text-indent: 247px">50% - 3px</p>
+<p style="text-indent: 247px">25% - 3px + 25%</p>
+<p style="text-indent: 247px">25% - 3px + 12.5% * 2</p>
+<p style="text-indent: 247px">25% - 3px + 12.5%*2</p>
+<p style="text-indent: 247px">25% - 3px + 2*12.5%</p>
+<p style="text-indent: 247px">25% - 3px + 2 * 12.5%</p>
+<p style="text-indent: 250px">30% + 20%</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-text-indent-1.html b/testing/web-platform/tests/css/css-values/calc-text-indent-1.html
new file mode 100644
index 0000000000..f1480f46e7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-text-indent-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: text-indent: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-text-indent-1-ref.html">
+<style type="text/css">
+
+body { width: 500px }
+p { font-size: 10px }
+
+</style>
+</head>
+<body>
+
+<p style="text-indent: calc(50% - 3px)">50% - 3px</p>
+<p style="text-indent: calc(25% - 3px + 25%)">25% - 3px + 25%</p>
+<p style="text-indent: calc(25% - 3px + 12.5% * 2)">25% - 3px + 12.5% * 2</p>
+<p style="text-indent: calc(25% - 3px + 12.5%*2)">25% - 3px + 12.5%*2</p>
+<p style="text-indent: calc(25% - 3px + 2*12.5%)">25% - 3px + 2*12.5%</p>
+<p style="text-indent: calc(25% - 3px + 2 * 12.5%)">25% - 3px + 2 * 12.5%</p>
+<p style="text-indent: calc(30% + 20%)">30% + 20%</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-text-indent-intrinsic-1-ref.html b/testing/web-platform/tests/css/css-values/calc-text-indent-intrinsic-1-ref.html
new file mode 100644
index 0000000000..6409ecc14a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-text-indent-intrinsic-1-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: intrinsic width of text-indent: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+body > div { margin: 0 0 1px 0; background: blue; color: white; height: 5px }
+
+</style>
+</head>
+<body>
+
+<div style="width: 7px"></div>
+<div style="width: 57px"></div>
+<div style="width: 60px"></div>
+<div style="width: 10px"></div>
+<div style="width: 60px"></div>
+<div style="width: 10px"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-text-indent-intrinsic-1.html b/testing/web-platform/tests/css/css-values/calc-text-indent-intrinsic-1.html
new file mode 100644
index 0000000000..fcae468942
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-text-indent-intrinsic-1.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: intrinsic width of text-indent: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-text-indent-intrinsic-1-ref.html">
+<style type="text/css">
+
+body { font-size: 10px }
+div { float: left; clear: left;
+ margin: 0 0 1px 0; background: blue; color: white; height: 5px }
+span { display: inline-block; width: 10px }
+
+</style>
+</head>
+<body>
+
+<div style="text-indent: calc(50% - 3px)"><span></span></div>
+<div style="text-indent: calc(5em - 3px)"><span></span></div>
+<div style="text-indent: calc(5em - 0%)"><span></span></div>
+<div style="text-indent: calc(50%)"><span></span></div>
+<div style="text-indent: calc(50px)"><span></span></div>
+<div style="text-indent: calc(25% + 25%)"><span></span></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-time-values.html b/testing/web-platform/tests/css/css-values/calc-time-values.html
new file mode 100644
index 0000000000..60bcdcba59
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-time-values.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: calc() function with time values</title>
+
+ <!--
+
+ Original test is:
+
+ https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/calc-with-time-angle-and-frequency-values.html
+
+ Issue 917718: [css-values] calc-with-time-angle-and-frequency-values
+ test is highly unreliable, transition-delay testing causes side effects
+ https://bugs.chromium.org/p/chromium/issues/detail?id=917718
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-computed-value">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#time">
+
+ <meta content="This test checks that additions, substractions, multiplications and divisions in calc() function when applied to time units." name="assert">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="log"></div>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function compareValue(property_name, calcValue, expectedValue, description)
+ {
+
+ test(function()
+ {
+
+ targetElement.style.setProperty(property_name, "inherit");
+
+ /*
+ Since we are running many consecutive tests on the same
+ element, then it is necessary to 'reset' its property
+ to an initial value before actually re-testing it.
+ */
+
+ targetElement.style.setProperty(property_name, calcValue);
+
+ var computedCalcValue = getComputedStyle(targetElement)[property_name];
+
+ targetElement.style.setProperty(property_name, expectedValue);
+
+ var computedExpectedValue = getComputedStyle(targetElement)[property_name];
+
+ assert_equals(computedCalcValue, computedExpectedValue);
+
+ }, description);
+
+ }
+
+
+ /* Testing time units */
+
+ /* compareValue(property_name, calcValue, expectedValue, description) */
+
+ compareValue("transition-delay", "calc(4s + 1s)", "5s", "addition of 2 time units: s plus s");
+
+ compareValue("transition-delay", "calc(4s + 1ms)", "4.001s", "addition of 2 time units: s plus ms");
+
+ compareValue("transition-delay", "calc(4ms + 1ms)", "0.005s", "addition of 2 time units: ms plus ms");
+
+ compareValue("transition-delay", "calc(4s - 1s)", "3s", "substraction of time unit: s minus s");
+
+ compareValue("transition-delay", "calc(4s - 1ms)", "3.999s", "substraction of time unit: s minus ms");
+
+ compareValue("transition-delay", "calc(4 * 1s)", "4s", "multiplication of integer with a time unit: int multiplied by s");
+
+ compareValue("transition-delay", "calc(4 * 1ms)", "0.004s", "multiplication of integer with a time unit: int multiplied by ms");
+
+ compareValue("transition-delay", "calc(4s / 2)", "2s", "division of time unit with integer: s divided by int");
+
+ compareValue("transition-delay", "calc(4ms / 2)", "0.002s", "division of time unit with integer: ms divided by int");
+
+ /* compareValue(property_name, calcValue, expectedValue, description) */
+
+
+
+ /* Testing conversion of time unit */
+
+ /* compareValue(property_name, calcValue, expectedValue, description) */
+
+ compareValue("transition-delay", "calc(4000ms)", "4s", "conversion of time unit: ms into s");
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-transform-origin-1-ref.html b/testing/web-platform/tests/css/css-values/calc-transform-origin-1-ref.html
new file mode 100644
index 0000000000..36f8f1945b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-transform-origin-1-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for calc() on transform-origin</title>
+ <link rel="author" title="L. David Baron" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594934">
+<style type="text/css">
+
+body { margin: 100px }
+
+p {
+ height: 50px; width: 200px;
+ background: yellow;
+ transform: rotate(15deg);
+}
+
+#one { transform-origin: 150px 20px; }
+#two { transform-origin: -22px -35px; }
+
+</style>
+</head>
+<body>
+<p id="one">hello</p>
+<p id="two">hello</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-transform-origin-1.html b/testing/web-platform/tests/css/css-values/calc-transform-origin-1.html
new file mode 100644
index 0000000000..d3817867f1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-transform-origin-1.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for calc() on transform-origin</title>
+ <link rel="author" title="L. David Baron" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594934">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-transform-origin-1-ref.html">
+<style type="text/css">
+
+body { margin: 100px }
+
+p {
+ height: 50px; width: 200px;
+ background: yellow;
+ transform: rotate(15deg);
+}
+
+#one { transform-origin: calc(50px + 50%) calc(100% - 30px); }
+#two { transform-origin: calc(-12.5% + 3px) calc(-10px - 50%); }
+
+</style>
+</head>
+<body>
+<p id="one">hello</p>
+<p id="two">hello</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-unit-analysis.html b/testing/web-platform/tests/css/css-values/calc-unit-analysis.html
new file mode 100644
index 0000000000..7508a39241
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-unit-analysis.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Variables Allowed Syntax</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#lengths" />
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-type-checking" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+<style id="style"></style>
+</head>
+<body>
+<div id=log></div>
+<div id="test"></div>
+<script>
+
+function run() {
+ var test_elt = document.getElementById("test");
+ var test_cs = window.getComputedStyle(test_elt, "");
+
+ function description_to_name(description) {
+ return description.replace(/\W+/g, "_").replace(/^_/, "").replace(/_$/, "");
+ }
+
+ function assert_invalid_value(property, value, description) {
+ test(function() {
+ test_elt.style.setProperty(property, "inherit");
+ test_elt.style.setProperty(property, value);
+ assert_equals(test_elt.style.getPropertyValue(property),
+ "inherit");
+ test_elt.style.setProperty(property, value);
+ test_elt.style.removeProperty(property);
+ },
+ description_to_name(description));
+ }
+
+ function assert_valid_value(property, value, computes_to, description) {
+ test(function() {
+ test_elt.style.setProperty(property, "inherit");
+ test_elt.style.setProperty(property, value);
+ assert_not_equals(test_elt.style.getPropertyValue(property),
+ "inherit");
+ assert_equals(test_cs.getPropertyValue(property),
+ computes_to);
+ test_elt.style.removeProperty(property);
+ },
+ description_to_name(description));
+ }
+
+ assert_invalid_value("margin-left", "calc(0)", // invalid calc expression
+ "unitless zero in calc() is a numeric type, not length");
+ assert_valid_value("margin-left", "calc(0px)", "0px",
+ "0px in calc()");
+ assert_invalid_value("margin-left", "calc(1px + 2)", // invalid calc expression
+ "addition of length and number");
+ assert_invalid_value("margin-left", "calc(2 + 1px)", // invalid calc expression
+ "addition of number and length");
+ assert_invalid_value("margin-left", "calc(1px - 2)", // invalid calc expression
+ "subtraction of length and number");
+ assert_invalid_value("margin-left", "calc(2 - 1px)", // invalid calc expression
+ "subtraction of number and length");
+ assert_valid_value("margin-left", "calc(2px * 2)", "4px",
+ "multiplication of length and number");
+ assert_valid_value("margin-left", "calc(2 * 2px)", "4px",
+ "multiplication of number and length");
+ assert_invalid_value("margin-left", "calc(2px * 1px)", // invalid calc expression
+ "multiplication of length and length");
+
+}
+
+run();
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-vertical-align-1-ref.html b/testing/web-platform/tests/css/css-values/calc-vertical-align-1-ref.html
new file mode 100644
index 0000000000..95d9d9ad70
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-vertical-align-1-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: Test for vertical-align:calc()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+
+<div style="line-height: 100px; margin-top: 100px">
+ <span>x</span>
+ <span style="vertical-align: 50px">x</span>
+ <span style="vertical-align: 50px">x</span>
+ <span style="vertical-align: 75px">x</span>
+ <span style="vertical-align: 45px">x</span>
+ <span style="vertical-align: 40px">x</span>
+ <span style="vertical-align: 30px">x</span>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-vertical-align-1.html b/testing/web-platform/tests/css/css-values/calc-vertical-align-1.html
new file mode 100644
index 0000000000..8e87ee7152
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-vertical-align-1.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: Test for vertical-align:calc()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-vertical-align-1-ref.html">
+
+<div style="line-height: 100px; margin-top: 100px">
+ <span>x</span>
+ <span style="vertical-align: calc(50px)">x</span>
+ <span style="vertical-align: calc(50%)">x</span>
+ <span style="vertical-align: calc(25px + 50%)">x</span>
+ <span style="vertical-align: calc(150% / 2 - 30px)">x</span>
+ <span style="vertical-align: calc(40px + 10% - 20% / 2)">x</span>
+ <span style="vertical-align: calc(40px - 10%)">x</span>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-width-block-1-ref.html b/testing/web-platform/tests/css/css-values/calc-width-block-1-ref.html
new file mode 100644
index 0000000000..6ab403568f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-width-block-1-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: width: calc() and min-width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+body { width: 500px }
+p { background: green; color: white; margin: 1px 0; font-size: 10px }
+
+</style>
+</head>
+<body>
+
+<p style="width: 247px">50% - 3px</p>
+<p style="width: 247px">25% - 3px + 25%</p>
+<p style="width: 247px">25% - 3px + 12.5% * 2</p>
+<p style="width: 247px">25% - 3px + 12.5%*2</p>
+<p style="width: 247px">25% - 3px + 2*12.5%</p>
+<p style="width: 247px">25% - 3px + 2 * 12.5%</p>
+<p style="width: 250px">30% + 20%</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-width-block-1.html b/testing/web-platform/tests/css/css-values/calc-width-block-1.html
new file mode 100644
index 0000000000..053b9800e9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-width-block-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-width-block-1-ref.html">
+<style type="text/css">
+
+body { width: 500px }
+p { background: green; color: white; margin: 1px 0; font-size: 10px }
+
+</style>
+</head>
+<body>
+
+<p style="width: calc(50% - 3px)">50% - 3px</p>
+<p style="width: calc(25% - 3px + 25%)">25% - 3px + 25%</p>
+<p style="width: calc(25% - 3px + 12.5% * 2)">25% - 3px + 12.5% * 2</p>
+<p style="width: calc(25% - 3px + 12.5%*2)">25% - 3px + 12.5%*2</p>
+<p style="width: calc(25% - 3px + 2*12.5%)">25% - 3px + 2*12.5%</p>
+<p style="width: calc(25% - 3px + 2 * 12.5%)">25% - 3px + 2 * 12.5%</p>
+<p style="width: calc(30% + 20%)">30% + 20%</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-width-block-intrinsic-1-ref.html b/testing/web-platform/tests/css/css-values/calc-width-block-intrinsic-1-ref.html
new file mode 100644
index 0000000000..2bc3a5f639
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-width-block-intrinsic-1-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: intrinsic width of width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+
+body > div { margin: 0 0 1px 0; background: blue; color: white; height: 5px }
+
+</style>
+</head>
+<body>
+
+<div style="width: 200px"></div>
+<div style="width: 47px"></div>
+<div style="width: 200px"></div>
+<div style="width: 200px"></div>
+<div style="width: 50px"></div>
+<div style="width: 200px"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-width-block-intrinsic-1.html b/testing/web-platform/tests/css/css-values/calc-width-block-intrinsic-1.html
new file mode 100644
index 0000000000..3d5c6d6737
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-width-block-intrinsic-1.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: intrinsic width of width: calc() on blocks</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-width-block-intrinsic-1-ref.html">
+<style type="text/css">
+
+body { font-size: 10px }
+body > div { float: left; clear: left;
+ margin: 0 0 1px 0; background: blue; color: white; height: 5px }
+body > div > div > div { width: 200px }
+
+</style>
+</head>
+<body>
+
+<div><div style="width: calc(50% - 3px)"><div></div></div></div>
+<div><div style="width: calc(5em - 3px)"><div></div></div></div>
+<div><div style="width: calc(5em - 0%)"><div></div></div></div>
+<div><div style="width: calc(50%)"><div></div></div></div>
+<div><div style="width: calc(50px)"><div></div></div></div>
+<div><div style="width: calc(25% + 25%)"><div></div></div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-width-table-auto-1-ref.html b/testing/web-platform/tests/css/css-values/calc-width-table-auto-1-ref.html
new file mode 100644
index 0000000000..d5a129dd02
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-width-table-auto-1-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: width: calc() on table-layout: auto tables</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<table border>
+ <tr>
+ <td style="width: 500px">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td>x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td style="width: 50%">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td>x</td>
+ <td style="width: 100px">y</td>
+</table>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-width-table-auto-1.html b/testing/web-platform/tests/css/css-values/calc-width-table-auto-1.html
new file mode 100644
index 0000000000..f556773c09
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-width-table-auto-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: width: calc() on table-layout: auto tables</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-width-table-auto-1-ref.html">
+<table border>
+ <tr>
+ <td style="width: calc(500px)">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td style="width: calc(50% + 1px)">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td style="width: calc(50%)">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td style="width: calc(2 * 10% + 0.5 * 500px)">x</td>
+ <td style="width: 100px">y</td>
+</table>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-width-table-fixed-1-ref.html b/testing/web-platform/tests/css/css-values/calc-width-table-fixed-1-ref.html
new file mode 100644
index 0000000000..f28ffcb858
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-width-table-fixed-1-ref.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Reference: width: calc() on table-layout: auto tables</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<style type="text/css">
+table { table-layout: fixed; width: 500px; border-spacing: 0 }
+</style>
+</head>
+<body>
+<table border>
+ <tr>
+ <td style="width: 500px">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td>x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td style="width: 50%">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td>x</td>
+ <td style="width: 100px">y</td>
+</table>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-width-table-fixed-1.html b/testing/web-platform/tests/css/css-values/calc-width-table-fixed-1.html
new file mode 100644
index 0000000000..1d1e976683
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-width-table-fixed-1.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>CSS Test: width: calc() on table-layout: auto tables</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+ <link rel="match" href="calc-width-table-fixed-1-ref.html">
+<style type="text/css">
+table { table-layout: fixed; width: 500px; border-spacing: 0 }
+</style>
+</head>
+<body>
+<table border>
+ <tr>
+ <td style="width: calc(500px)">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td style="width: calc(50% + 1px)">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td style="width: calc(50%)">x</td>
+ <td style="width: 100px">y</td>
+</table>
+<table border>
+ <tr>
+ <td style="width: calc(2 * 10% + 0.5 * 500px)">x</td>
+ <td style="width: 100px">y</td>
+</table>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/calc-z-index-fractions-001.html b/testing/web-platform/tests/css/css-values/calc-z-index-fractions-001.html
new file mode 100644
index 0000000000..eef8032169
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-z-index-fractions-001.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: computed value of 'z-index' when specified with calc() function and fractional values</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#calc-range">
+
+ <meta content="This test verifies how 2 calc() functions are computed for 'z-index' when involved expressions end up being numbers halfway between adjacent integers." name="assert">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description)
+ {
+
+ test(function()
+ {
+
+ targetElement.style.setProperty(property_name, initial_value);
+
+ /*
+ The purpose of the initial_value is to act as a fallback
+ value in case the calc() function in the specified value
+ fails or in case it generates an invalid value. Since we
+ are running 2 consecutive tests on the same element,
+ then it is necessary to reset its property to an initial
+ value.
+ */
+
+ targetElement.style.setProperty(property_name, specified_value);
+
+ assert_equals(getComputedStyle(targetElement)[property_name], expected_value);
+
+ }, description);
+ }
+
+ /* verifyComputedStyle(property_name, initial_value, specified_value, expected_value, description) */
+
+ verifyComputedStyle("z-index", "auto", "calc(3 / 2)", "2", "testing z-index: calc(3 / 2)");
+
+ verifyComputedStyle("z-index", "auto", "calc(-3 / 2)", "-1", "testing z-index: calc(-3 / 2)");
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/calc-zero-percent-height.html b/testing/web-platform/tests/css/css-values/calc-zero-percent-height.html
new file mode 100644
index 0000000000..ffb2ecd6dc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/calc-zero-percent-height.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<link rel="help" href="https://www.w3.org/TR/css-values-4/#calc-computed-value">
+<link rel="help" href="https://www.w3.org/TR/CSS2/visudet.html#the-height-property">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<title>0% in calc() should be preserved</title>
+<script>
+CSS.registerProperty({
+ name: '--custom-height',
+ syntax: '<length-percentage>',
+ initialValue: 'calc(0% + 0px)',
+ inherits: false
+});
+</script>
+<style>
+.height-filler {
+ height: 100px;
+}
+
+.test {
+ width: 100px;
+ height: var(--custom-height);
+ background-color: green;
+}
+</style>
+<p>Test passes if there is a filled green square.</p>
+<div class="test">
+ <div class="height-filler">
+ </div>
+</div>
diff --git a/testing/web-platform/tests/css/css-values/cap-unit-001.html b/testing/web-platform/tests/css/css-values/cap-unit-001.html
new file mode 100644
index 0000000000..ef12127754
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/cap-unit-001.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the cap unit</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<link rel="match" href="reference/cap-unit-001-ref.html">
+<meta name="assert" content="The cap unit is equal to the used cap-height of the first available font.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<style>
+span {
+ background: green;
+ color: green;
+ position: absolute;
+}
+div {
+ font: 50px Ahem; /* cap-height of Ahem is 0.8em */
+ background: red;
+ position: relative;
+ height: 180px;
+ height: calc(180px - 2cap); /* reduce to 100px if cap correctly supported */
+ width: 100px;
+}
+
+div span {
+ width: 2.5cap;
+ height: 100px;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div><span></span></div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/ch-empty-pseudo-recalc-on-font-load.html b/testing/web-platform/tests/css/css-values/ch-empty-pseudo-recalc-on-font-load.html
new file mode 100644
index 0000000000..7ad2b85fa4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-empty-pseudo-recalc-on-font-load.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Length unit 'ch' used in pseudo elements without text should be recalculated after loading a web font</title>
+<link rel="help" href="https://www.w3.org/TR/css-font-loading-3/#font-face-load">
+<link rel="help" href="https://www.w3.org/TR/css-values-3/#font-relative-lengths">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4#generated-content">
+<link rel="author" href="xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+.before::before,
+.after::after,
+.backdrop::backdrop {
+ font: 25px/1 "custom font", monospace;
+ background: linear-gradient(45deg, red, blue);
+ background-size: 1ch 1ch;
+}
+</style>
+
+<div class="container before"></div>
+<div class="container after"></div>
+<dialog class="container backdrop"></dialog>
+
+<script>
+function parseBackgroundSizeInPx(element, pseudoElement) {
+ const x = getComputedStyle(element, pseudoElement).backgroundSize.split(' ')[0];
+ if (!x.endsWith('px'))
+ return NaN;
+ return parseFloat(x);
+}
+
+const testCases = ['before', 'after', 'backdrop'];
+const elements = testCases.map(testCase => document.querySelector('.' + testCase));
+const asyncTests = testCases.map(
+ testCase => async_test(`ch in pseudo-element ::${testCase} should be recalculated after loading a web font`));
+
+// Before loading custom font, tests should be rendered with monospace
+// fallback and have a '1ch' measurement much shorter than 25px.
+for (let i = 0; i < testCases.length; ++i) {
+ asyncTests[i].step(() => {
+ const backgroundSizePx = parseBackgroundSizeInPx(elements[i], '::' + testCases[i]);
+ assert_less_than(backgroundSizePx, 24);
+ });
+}
+
+// Insert custom font into style sheet and load it
+const customFont = new FontFace('custom font', 'url(/fonts/Ahem.ttf)');
+document.fonts.add(customFont);
+
+// After loading custom font, tests should be rendered with the custom font,
+// which is Ahem, and have a '1ch' measurement that equals 25px.
+customFont.load().then(
+ () => {
+ for (let i = 0; i < testCases.length; ++i) {
+ asyncTests[i].step(() => {
+ const backgroundSizePx = parseBackgroundSizeInPx(elements[i], '::' + testCases[i]);
+ assert_equals(backgroundSizePx, 25);
+ asyncTests[i].done();
+ });
+ }
+ },
+ () => {
+ for (let i = 0; i < testCases.length; ++i) {
+ asyncTests[i].step(() => {
+ assert_unreached('Failed to load font');
+ });
+ }
+ }
+);
+</script>
diff --git a/testing/web-platform/tests/css/css-values/ch-pseudo-recalc-on-font-load.html b/testing/web-platform/tests/css/css-values/ch-pseudo-recalc-on-font-load.html
new file mode 100644
index 0000000000..c8a275cfb3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-pseudo-recalc-on-font-load.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Length unit 'ch' used in pseudo elements should be recalculated after loading a web font</title>
+<link rel="help" href="https://www.w3.org/TR/css-font-loading-3/#font-face-load">
+<link rel="help" href="https://www.w3.org/TR/css-values-3/#font-relative-lengths">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#first-letter-styling">
+<link rel="author" href="xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+.container {
+ font: 25px/1 "custom font", monospace;
+}
+
+.before::before,
+.after::after,
+.first-letter::first-letter,
+.first-line::first-line {
+ font-family: monospace;
+ font-size: 1ch; /* Refers to originating element's font metrics, which are different from self font metrics. */
+}
+
+.before::before,
+.after::after {
+ content: 'text';
+}
+
+/* Defined separately so that browsers that haven't shipped it can still pass other tests. */
+.marker::marker {
+ font-family: monospace;
+ font-size: 1ch;
+ content: 'text';
+}
+
+</style>
+
+<div class="container before"></div>
+<div class="container after"></div>
+<div class="container first-letter">text</div>
+<div class="container first-line">text</div>
+<li class="container marker"></li>
+
+<script>
+function parseFontSizeInPx(element, pseudoElement) {
+ const value = getComputedStyle(element, pseudoElement).fontSize;
+ if (!value.endsWith('px'))
+ return NaN;
+ return parseFloat(value);
+}
+
+const testCases = ['before', 'after', 'first-letter', 'first-line', 'marker'];
+const elements = testCases.map(testCase => document.querySelector('.' + testCase));
+const asyncTests = testCases.map(
+ testCase => async_test(`ch in pseudo-element ::${testCase} should be recalculated after loading a web font`));
+
+// Before loading custom font, tests should be rendered with monospace
+// fallback and have a '1ch' measurement much shorter than 25px.
+for (let i = 0; i < testCases.length; ++i) {
+ asyncTests[i].step(() => {
+ const fontSizePx = parseFontSizeInPx(elements[i], '::' + testCases[i]);
+ assert_less_than(fontSizePx, 24);
+ });
+}
+
+// Insert custom font into style sheet and load it
+const customFont = new FontFace('custom font', 'url(/fonts/Ahem.ttf)');
+document.fonts.add(customFont);
+
+// After loading custom font, tests should be rendered with the custom font,
+// which is Ahem, and have a '1ch' measurement that equals 25px.
+customFont.load().then(
+ () => {
+ for (let i = 0; i < testCases.length; ++i) {
+ asyncTests[i].step(() => {
+ const fontSizePx = parseFontSizeInPx(elements[i], '::' + testCases[i]);
+ assert_approx_equals(fontSizePx, 25, 0.1);
+ asyncTests[i].done();
+ });
+ }
+ },
+ () => {
+ for (let i = 0; i < testCases.length; ++i) {
+ asyncTests[i].step(() => {
+ assert_unreached('Failed to load font');
+ });
+ }
+ }
+);
+</script>
diff --git a/testing/web-platform/tests/css/css-values/ch-recalc-on-font-load.html b/testing/web-platform/tests/css/css-values/ch-recalc-on-font-load.html
new file mode 100644
index 0000000000..b13f643ebe
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-recalc-on-font-load.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<title>Length unit 'ch' should be recalculated after loading a web font</title>
+<link rel="help" href="https://www.w3.org/TR/css-font-loading-3/#font-face-load">
+<link rel="help" href="https://www.w3.org/TR/css-values-3/#font-relative-lengths">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+.container {
+ font: 25px/1 "custom font", monospace;
+}
+
+.test {
+ width: 1ch;
+}
+</style>
+
+<div class="container">
+ <div class="test"></div>
+</div>
+
+<div class="container" style="display: contents">
+ <div class="test"></div>
+</div>
+
+<div class="container" style="display: none">
+ <div class="test"></div>
+</div>
+
+<script>
+function parseWidthInPx(element) {
+ const value = getComputedStyle(element).width;
+ if (!value.endsWith('px'))
+ return NaN;
+ return parseFloat(value);
+}
+
+const testCases = document.querySelectorAll('.test');
+
+const asyncTests = [
+ async_test('ch in a normal div should be recalculated after loading a web font'),
+ async_test('ch in display:contents should be recalculated after loading a web font'),
+ async_test('ch in display:none should be recalculated after loading a web font')
+];
+
+// Before loading custom font, tests should be rendered with monospace
+// fallback and have a '1ch' measurement much shorter than 25px.
+for (let i = 0; i < testCases.length; ++i) {
+ asyncTests[i].step(() => {
+ const widthPx = parseWidthInPx(testCases[i]);
+ assert_less_than(widthPx, 24);
+ });
+}
+
+// Insert custom font into style sheet and load it
+const customFont = new FontFace('custom font', 'url(/fonts/Ahem.ttf)');
+document.fonts.add(customFont);
+
+// After loading custom font, tests should be rendered with the custom font,
+// which is Ahem, and have a '1ch' measurement that equals 25px.
+customFont.load().then(
+ () => {
+ for (let i = 0; i < testCases.length; ++i) {
+ asyncTests[i].step(() => {
+ const widthPx = parseWidthInPx(testCases[i]);
+ assert_approx_equals(widthPx, 25, 0.1);
+ asyncTests[i].done();
+ });
+ }
+ },
+ () => {
+ for (let i = 0; i < testCases.length; ++i) {
+ asyncTests[i].step(() => {
+ assert_unreached('Failed to load font');
+ });
+ }
+ }
+);
+</script>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-001.html b/testing/web-platform/tests/css/css-values/ch-unit-001.html
new file mode 100644
index 0000000000..dc89b84156
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-001.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ch unit</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<link rel="match" href="reference/ch-unit-001-ref.html">
+<meta name="assert" content="The ch unit is equal to the used advance measure of the 0 (ZERO, U+0030) glyph found in the font used to render it.">
+<style>
+span {
+ background: green;
+ color: green;
+ top: 0; bottom: 0;
+ position: absolute;
+}
+div {
+ background: red;
+ color: red;
+ position: relative;
+ height: 10ch;
+ width: 5ch;
+ float: left;
+}
+
+div + div {
+ width: auto;
+}
+
+div + div span {
+ width: 5ch;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div><span>00000</span></div>
+ <div><span></span>00000</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-002.html b/testing/web-platform/tests/css/css-values/ch-unit-002.html
new file mode 100644
index 0000000000..0f4fcb371c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-002.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: the ch unit in vertical orientation</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#block-flow">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#text-orientation">
+<link rel="match" href="reference/ch-unit-002-ref.html">
+<meta name="assert" content="In vertical upright, the ch unit is equal to the used vertical advance measure of the 0 (ZERO, U+0030) glyph found in the font used to render it.">
+<style>
+span {
+ background: green;
+ color: green;
+ left: 0; right: 0;
+ position: absolute;
+}
+div {
+ background: red;
+ color: red;
+ position: relative;
+ height: 5ch;
+ width: 10ch;
+ writing-mode: vertical-rl;
+ text-orientation: upright;
+}
+
+div + div {
+ height: auto;
+}
+
+div + div span {
+ height: 5ch;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div><span>00000</span></div>
+ <div><span></span>00000</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-003.html b/testing/web-platform/tests/css/css-values/ch-unit-003.html
new file mode 100644
index 0000000000..a41a1689ad
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-003.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ch unit</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<link rel="match" href="reference/ch-unit-001-ref.html">
+<meta name="assert" content="In vertical mixed, The ch unit is equal to the used horizontal advance measure of the 0 (ZERO, U+0030) glyph found in the font used to render it.">
+<style>
+span {
+ background: green;
+ color: green;
+ left: 0; right: 0;
+ position: absolute;
+}
+div {
+ background: red;
+ color: red;
+ position: relative;
+ height: 5ch;
+ width: 10ch;
+ writing-mode: vertical-rl;
+ text-orientation: mixed;
+}
+
+div + div {
+ height: auto;
+}
+
+div + div span {
+ height: 5ch;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div><span>00000</span></div>
+ <div><span></span>00000</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-004.html b/testing/web-platform/tests/css/css-values/ch-unit-004.html
new file mode 100644
index 0000000000..1c2f818ce6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-004.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ch unit</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<link rel="match" href="reference/ch-unit-001-ref.html">
+<meta name="assert" content="In vertical sideways, The ch unit is equal to the used horizontal advance measure of the 0 (ZERO, U+0030) glyph found in the font used to render it.">
+<style>
+span {
+ background: green;
+ color: green;
+ left: 0; right: 0;
+ position: absolute;
+}
+div {
+ background: red;
+ color: red;
+ position: relative;
+ height: 5ch;
+ width: 10ch;
+ writing-mode: vertical-rl;
+ text-orientation: sideways;
+}
+
+div + div {
+ height: auto;
+}
+
+div + div span {
+ height: 5ch;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div><span>00000</span></div>
+ <div><span></span>00000</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-008.html b/testing/web-platform/tests/css/css-values/ch-unit-008.html
new file mode 100644
index 0000000000..0af7a6e62b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-008.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ch unit in width (basic)</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#font-relative-lengths">
+ <link rel="match" href="reference/ch-unit-008-ref.html">
+
+
+ <style>
+ div
+ {
+ font-size: 80px; /* arbitrary font size */
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 1.8em;
+ width: 5ch;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ color: orange;
+ float: left;
+ line-height: 1.8; /* arbitrary line-height */
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same width</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">00000</div>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-009.html b/testing/web-platform/tests/css/css-values/ch-unit-009.html
new file mode 100644
index 0000000000..24d6451893
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-009.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ch unit in height (basic)</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#font-relative-lengths">
+ <link rel="match" href="reference/ch-unit-009-ref.html">
+
+
+ <style>
+ div
+ {
+ float: left;
+ font-size: 80px; /* arbitrary font size */
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 5ch;
+ width: 1.8em;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ color: orange;
+ line-height: 1.8; /* arbitrary line-height */
+ writing-mode: vertical-rl;
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">00000</div>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-010.html b/testing/web-platform/tests/css/css-values/ch-unit-010.html
new file mode 100644
index 0000000000..935dc7647f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-010.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ch unit in height with 'text-orientation: mixed'</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#font-relative-lengths">
+ <link rel="match" href="reference/ch-unit-009-ref.html">
+
+ <meta name="assert" content="In this test, the ch unit is the advance width measure of the 0 (ZERO, U+0030) glyph.">
+
+ <style>
+ div
+ {
+ float: left;
+ font-size: 80px; /* arbitrary font size */
+ text-orientation: mixed;
+ writing-mode: vertical-rl;
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 5ch;
+ width: 1.8em;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ color: orange;
+ line-height: 1.8; /* arbitrary line-height */
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">00000</div>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-011.html b/testing/web-platform/tests/css/css-values/ch-unit-011.html
new file mode 100644
index 0000000000..6d39d554da
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-011.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ch unit in height with 'text-orientation: upright'</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#font-relative-lengths">
+ <link rel="match" href="reference/ch-unit-011-ref.html">
+
+ <meta name="assert" content="In this test, the ch unit is the advance height measure of the 0 (ZERO, U+0030) glyph.">
+
+ <style>
+ div
+ {
+ float: left;
+ font-size: 80px; /* arbitrary font size */
+ text-orientation: upright;
+ writing-mode: vertical-rl;
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 5ch;
+ width: 1.8em;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ color: orange;
+ line-height: 1.8; /* arbitrary line-height */
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">00000</div>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-012.html b/testing/web-platform/tests/css/css-values/ch-unit-012.html
new file mode 100644
index 0000000000..4f04eb598a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-012.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ch unit in height with 'text-orientation: sideways'</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#font-relative-lengths">
+ <link rel="match" href="reference/ch-unit-009-ref.html">
+
+ <meta name="assert" content="In this test, the ch unit is the advance width measure of the 0 (ZERO, U+0030) glyph.">
+
+ <style>
+ div
+ {
+ float: left;
+ font-size: 80px; /* arbitrary font size */
+ text-orientation: sideways;
+ writing-mode: vertical-rl;
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 5ch;
+ width: 1.8em;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ color: orange;
+ line-height: 1.8; /* arbitrary line-height */
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">00000</div>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-016.html b/testing/web-platform/tests/css/css-values/ch-unit-016.html
new file mode 100644
index 0000000000..ce20d5f598
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-016.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ch unit</title>
+<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<link rel="match" href="reference/ch-unit-016-ref.html">
+<meta name="assert" content="The ch unit is equal to 0em if the zero glyph's advance is 0.">
+<style>
+@font-face {
+ font-family: ChTestZeroWidthZero;
+ src: url(resources/ChTestZeroWidthZero.woff);
+}
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+}
+.test {
+ width: calc(100px + 5ch);
+}
+.ref {
+ width: 100px;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<!-- The '0' glyph in ChTestZeroWidthZero has a horizontal advance of
+ zero, so ch units should compute to 0em, resulting in the div being
+ 100px wide. -->
+<div class="test" style="font: 20px ChTestZeroWidthZero;"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-017.html b/testing/web-platform/tests/css/css-values/ch-unit-017.html
new file mode 100644
index 0000000000..3959feec80
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-017.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ch unit</title>
+<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<link rel="match" href="reference/ch-unit-016-ref.html">
+<meta name="assert" content="In vertical upright writing modes, the ch unit is equal to the vertical advance of the zero glyph.">
+<style>
+@font-face {
+ font-family: ChTestShortZero;
+ src: url(resources/ChTestShortZero.woff);
+}
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+}
+.test {
+ writing-mode: vertical-rl;
+ text-orientation: upright;
+ width: 5ch;
+}
+.ref {
+ width: 100px;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<!-- ChTestShortZero has a '0' glyph whose vertical advance is a quarter
+ of the units per em, so ch units in vertical upright writing modes
+ should compute to 0.25em, resulting in the div being 100px width. -->
+<div class="test" style="font: 80px ChTestShortZero;"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/ch-unit-018.html b/testing/web-platform/tests/css/css-values/ch-unit-018.html
new file mode 100644
index 0000000000..d79fec7f49
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ch-unit-018.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ch unit</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#ch">
+<link rel="match" href="reference/ch-unit-016-ref.html">
+<meta name="assert" content="The ch unit = the used advance measure of the “0” (ZERO, U+0030) glyph in the font used to render it">
+<style>
+@font-face {
+ font-family: NoDigits;
+ src: local(Ahem), url("/fonts/Ahem.ttf");
+ unicode-range: U+0000-002F, U+003A-007F;
+}
+@font-face {
+ font-family: ChTestZeroWidthZero;
+ src: url("resources/ChTestZeroWidthZero.woff");
+}
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+}
+.test {
+ width: calc(100px + 5ch);
+}
+.ref {
+ width: 100px;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<!-- NoDigits excludes the ASCII digits, and therefore should NOT be used
+ to derive the size of the 'ch' unit, which should instead be based on the
+ '0' in ChTestZeroWidthZero, which is zero-width. -->
+<div class="test" style="font: 80px NoDigits, ChTestZeroWidthZero;"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/clamp-length-computed.html b/testing/web-platform/tests/css/css-values/clamp-length-computed.html
new file mode 100644
index 0000000000..8ace5b9550
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/clamp-length-computed.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/computed-testcommon.js"></script>
+<div id="container" style="font-size: 20px">
+ <div id="target"></div>
+ <div id="reference"></div>
+</div>
+<script>
+const property = 'letter-spacing';
+
+function test_length_equals(value, expected) {
+ const reference = document.getElementById('reference');
+ reference.style[property] = '';
+ reference.style[property] = expected;
+ const computed = getComputedStyle(reference)[property];
+ test_computed_value(property, value, computed);
+}
+
+test_length_equals('clamp(10px, 20px, 30px)', '20px');
+test_length_equals('clamp(10px, 5px, 30px)', '10px');
+test_length_equals('clamp(10px, 35px, 30px)', '30px');
+test_length_equals('clamp(10px, 35px , 30px)', '30px');
+test_length_equals('clamp(10px, 35px /*foo*/, 30px)', '30px');
+test_length_equals('clamp(10px /* foo */ , 35px, 30px)', '30px');
+test_length_equals('clamp(10px , 35px, 30px)', '30px');
+
+// clamp(MIN, VAL, MAX) is identical to max(MIN, min(VAL, MAX)),
+// so MIN wins over MAX if they are in the wrong order.
+test_length_equals('clamp(30px, 100px, 20px)', '30px');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/clamp-length-invalid.html b/testing/web-platform/tests/css/css-values/clamp-length-invalid.html
new file mode 100644
index 0000000000..83758173be
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/clamp-length-invalid.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_length(value) {
+ test_invalid_value('letter-spacing', value);
+}
+
+test_invalid_length('clamp()');
+test_invalid_length('clamp( )');
+test_invalid_length('clamp(,)');
+test_invalid_length('clamp(1px, )');
+test_invalid_length('clamp(, 1px)');
+test_invalid_length('clamp(1px, 1px)');
+test_invalid_length('clamp(1px, , 1px)');
+test_invalid_length('clamp(, 1px, 1px)');
+test_invalid_length('clamp(1px, 1px, )');
+test_invalid_length('clamp(1px, 1px, 1px, )');
+test_invalid_length('clamp(1px 1px 1px)');
+test_invalid_length('clamp(0, 10rem, 100%)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/clamp-length-serialize.html b/testing/web-platform/tests/css/css-values/clamp-length-serialize.html
new file mode 100644
index 0000000000..d9b4e6f988
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/clamp-length-serialize.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_valid_length(value, expected) {
+ test_valid_value('letter-spacing', value, expected);
+}
+
+test_valid_length('clamp(1px, 2px, 3px)', 'calc(2px)');
+test_valid_length('clamp(1px, 2px, clamp(2px, 3px, 4px))', 'calc(2px)');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/crashtests/viewport-unit-inline-style-crash.html b/testing/web-platform/tests/css/css-values/crashtests/viewport-unit-inline-style-crash.html
new file mode 100644
index 0000000000..4c38e18781
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/crashtests/viewport-unit-inline-style-crash.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Don't crash when setting viewport units on inline style</title>
+<link rel="help" href="https://crbug.com/1402548">
+<div id="div">
+ PASS if no crash
+</div>
+<script>
+ div.style.setProperty("margin-bottom", "1px");
+ div.offsetTop;
+ div.style.setProperty("margin-bottom", "1vh");
+</script>
diff --git a/testing/web-platform/tests/css/css-values/dynamic-viewport-units-rule-cache.html b/testing/web-platform/tests/css/css-values/dynamic-viewport-units-rule-cache.html
new file mode 100644
index 0000000000..8afb3c51ed
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/dynamic-viewport-units-rule-cache.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-values/#viewport-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body style="display: none">
+<script>
+ promise_test(async function() {
+ let frame = document.createElement("iframe");
+ let load = new Promise(resolve => {
+ frame.addEventListener("load", resolve);
+ });
+ frame.setAttribute("scrolling", "no");
+ frame.setAttribute("frameborder", "0");
+ frame.style.width = "100px";
+ frame.style.height = "100px";
+ frame.srcdoc = `
+ <!doctype html>
+ <style>
+ body { margin: 0 }
+ #parent, #child { width: 100vw; height: 100vh; }
+ </style>
+ <div id="parent">
+ <div id="child"></div>
+ </div>
+ `;
+ document.body.appendChild(frame);
+
+ await load;
+
+ {
+ let resize = new Promise(resolve => {
+ frame.contentWindow.addEventListener("resize", resolve);
+ });
+ document.body.style.display = "";
+ await resize;
+ }
+
+ let doc = frame.contentDocument;
+ function assertDimensions(expected, description) {
+ for (let id of ["parent", "child"]) {
+ let element = doc.getElementById(id);
+ let rect = element.getBoundingClientRect();
+ assert_equals(rect.width, expected, `${description}: ${id} width`);
+ assert_equals(rect.height, expected, `${description}: ${id} height`);
+ }
+ }
+ assertDimensions(100, "before resize");
+ let resize = new Promise(resolve => {
+ frame.contentWindow.addEventListener("resize", resolve);
+ });
+ frame.style.width = "200px";
+ frame.style.height = "200px";
+ await resize;
+ assertDimensions(200, "after resize");
+ })
+</script>
diff --git a/testing/web-platform/tests/css/css-values/ex-calc-expression-001-ref.html b/testing/web-platform/tests/css/css-values/ex-calc-expression-001-ref.html
new file mode 100644
index 0000000000..888a51ea9b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ex-calc-expression-001-ref.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+div {
+ width: 2ex;
+ height: 2ex;
+ background: green;
+}
+</style>
+<div></div>
diff --git a/testing/web-platform/tests/css/css-values/ex-calc-expression-001.html b/testing/web-platform/tests/css/css-values/ex-calc-expression-001.html
new file mode 100644
index 0000000000..4eab829697
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ex-calc-expression-001.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test: Calc expression using multiple ex operands</title>
+<link rel="match" href="ex-calc-expression-001-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-values/#funcdef-calc">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+/*
+ This is a regression test for:
+ https://github.com/servo/servo/pull/18807
+ https://bugzilla.mozilla.org/show_bug.cgi?id=1407092
+ */
+div {
+ width: calc(1ex + 1ex);
+ height: calc(1ex + 1ex);
+ background: green;
+}
+</style>
+<div></div>
diff --git a/testing/web-platform/tests/css/css-values/ex-unit-001.html b/testing/web-platform/tests/css/css-values/ex-unit-001.html
new file mode 100644
index 0000000000..b147c1cc98
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ex-unit-001.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: ex unit computation and dependencies</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-values/#font-relative-lengths">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1529537">
+<link rel="match" href="reference/ex-unit-001-ref.html">
+<meta name="flags" content="ahem">
+<style>
+ @font-face {
+ font-family: foo;
+ src: url('/fonts/Ahem.ttf');
+ }
+
+ @font-face {
+ font-family: foo;
+ font-weight: 900;
+ /* A font with significantly different ex-height metric than Aham. */
+ src: url('/fonts/noto/noto-sans-v8-latin-regular.woff');
+ }
+
+ div {
+ font-family: foo, sans-serif;
+ width: 10ex;
+ height: 20px;
+ background: blue;
+ margin: 20px;
+ font-size: 20px;
+ }
+</style>
+<p>All lines except the first should be the same length</p>
+<div></div>
+<div style="font-weight: 900"></div>
+<div style="font-weight: 900; width: 10ex;"></div>
+<section style="font-weight: 900"><div></div></section>
diff --git a/testing/web-platform/tests/css/css-values/ex-unit-002.html b/testing/web-platform/tests/css/css-values/ex-unit-002.html
new file mode 100644
index 0000000000..a0293cf45b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ex-unit-002.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ex unit</title>
+<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<link rel="match" href="reference/ex-unit-002-ref.html">
+<meta name="assert" content="The ex unit equals the x-height of the first available font if it has reliable metrics for the x-height.">
+<style>
+@font-face {
+ font-family: ExTest;
+ src: url(resources/ExTest.woff);
+}
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+}
+.test {
+ width: 10ex;
+}
+.ref {
+ width: 100px;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<!-- ExTest is a font whose OS/2 table's sxHeight field is set to an
+ eighth of the font's units per em, so ex units should compute to
+ 0.125em, resulting in the div being 100px wide. -->
+<div class="test" style="font: 80px ExTest;"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/ex-unit-003.html b/testing/web-platform/tests/css/css-values/ex-unit-003.html
new file mode 100644
index 0000000000..67bb0c6eb3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ex-unit-003.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ex unit</title>
+<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<link rel="match" href="reference/ex-unit-002-ref.html">
+<meta name="assert" content="Even in vertical writing modes, the ex unit equals the x-height of the first available font if it has reliable metrics for the x-height.">
+<style>
+@font-face {
+ font-family: ExTest;
+ src: url(resources/ExTest.woff);
+}
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+}
+.test {
+ writing-mode: vertical-rl;
+ width: 10ex;
+}
+.ref {
+ width: 100px;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<!-- ExTest is a font whose OS/2 table's sxHeight field is set to an
+ eighth of the font's units per em, so ex units should compute to
+ 0.125em, resulting in the div being 100px wide. -->
+<div class="test" style="font: 80px ExTest;"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/ex-unit-004.html b/testing/web-platform/tests/css/css-values/ex-unit-004.html
new file mode 100644
index 0000000000..1edf97d4ea
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ex-unit-004.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ex unit</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#first-available-font">
+<link rel="match" href="reference/ex-unit-004-ref.html">
+<meta name="assert" content="The ex unit equals the x-height of the first available font if it has reliable metrics for the x-height.">
+<style>
+@font-face {
+ font-family: ExTestNoSpace;
+ src: url(resources/ExTest-NoSpace.woff);
+ unicode-range: U+0021-00FF;
+}
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+ font-size: 80px;
+ width: 10ex;
+}
+.test {
+ font-family: ExTestNoSpace, Arial, sans-serif;
+}
+.ref {
+ font-family: Arial, sans-serif;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<!-- ExTest is a font whose OS/2 table's sxHeight field is set to an
+ eighth of the font's units per em, but the space character is excluded
+ by unicode-range and therefore it is not valid as "first available font"
+ per CSS Fonts, and must NOT be used as the basis of the 'ex' unit. -->
+<div class="test"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/exp-log-compute.html b/testing/web-platform/tests/css/css-values/exp-log-compute.html
new file mode 100644
index 0000000000..3fa2400044
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/exp-log-compute.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<script>
+// Simple tests
+test_math_used('log(1)', '0', {type:'number'});
+test_math_used('log(10, 10)', '1', {type:'number'});
+test_math_used('exp(0)', '1', {type:'number'});
+
+// Test e
+test_math_used('calc(log(e) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(e - exp(1))', '0', {type:'number', approx:0.1});
+
+//General calculations
+test_math_used('calc(log( 1 + 1 + 2 /2 - 2) )', '0', {type:'number', approx:0.1});
+test_math_used('calc(log(1) + exp(0))', '1', {type:'number', approx:0.1});
+test_math_used('calc(exp(log(1) + exp(0)*2))', '7.4', {type:'number', approx:0.1});
+test_math_used('calc(log(log(1) + exp(0)*10))', '2.3', {type:'number', approx:0.1});
+test_math_used('calc(log(log(1) + exp(0)*20, 10))', '1.3', {type:'number', approx:0.1});
+test_math_used('calc(log(e) / log(e) + exp(0)*2 * log(e))', '3', {type:'number', approx:0.1});
+test_math_used('calc(log((1 + 1) /2) / log(e) + exp(0*1)*2 * log(e))', '2', {type:'number', approx:0.1});
+test_math_used('calc(log((3 + 1) /2, 2) / log(e) + exp(0*1)*2 * log(e))', '3', {type:'number', approx:0.1});
+test_math_used('calc(log((3 + 1) /2, 2) / log(e, e) + exp(0*1)*2 * log(e, e))', '3', {type:'number', approx:0.1});
+test_math_used('calc(exp(0) + 1)', '2', {type:'number', approx:0.1});
+
+// Test nesting
+test_math_used('calc(log(exp(1)))', '1', {type:'number', approx:0.1});
+test_math_used('calc(log(exp(log(e))))', '1', {type:'number', approx:0.1});
+</script>
diff --git a/testing/web-platform/tests/css/css-values/exp-log-invalid.html b/testing/web-platform/tests/css/css-values/exp-log-invalid.html
new file mode 100644
index 0000000000..7fa56dc5bc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/exp-log-invalid.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_number(value) {
+ test_invalid_value('opacity', value);
+}
+
+// Syntax checking
+test_invalid_number('exp()');
+test_invalid_number('exp( )');
+test_invalid_number('exp(,)');
+test_invalid_number('exp(1, )');
+test_invalid_number('exp(, 1)');
+test_invalid_number('exp(1 + )');
+test_invalid_number('exp(1 - )');
+test_invalid_number('exp(1 * )');
+test_invalid_number('exp(1 / )');
+test_invalid_number('exp(1 2)');
+test_invalid_number('exp(1, , 2)');
+test_invalid_number('log()');
+test_invalid_number('log( )');
+test_invalid_number('log(,)');
+test_invalid_number('log(1, )');
+test_invalid_number('log(, 1)');
+test_invalid_number('log(1 + )');
+test_invalid_number('log(1 - )');
+test_invalid_number('log(1 * )');
+test_invalid_number('log(1 / )');
+test_invalid_number('log(1 2)');
+test_invalid_number('log(1, , 2)');
+
+// Type checking
+test_invalid_number('exp(0px)');
+test_invalid_number('exp(0s)');
+test_invalid_number('exp(0deg)');
+test_invalid_number('exp(0Hz)');
+test_invalid_number('exp(0dpi)');
+test_invalid_number('exp(0fr)');
+test_invalid_number('exp(1, 1%)');
+test_invalid_number('exp(1, 0px)');
+test_invalid_number('exp(1, 0s)');
+test_invalid_number('exp(1, 0deg)');
+test_invalid_number('exp(1, 0Hz)');
+test_invalid_number('exp(1, 0dpi)');
+test_invalid_number('exp(1, 0fr)');
+test_invalid_number('log(0px)');
+test_invalid_number('log(0s)');
+test_invalid_number('log(0deg)');
+test_invalid_number('log(0Hz)');
+test_invalid_number('log(0dpi)');
+test_invalid_number('log(0fr)');
+test_invalid_number('log(1, 1%)');
+test_invalid_number('log(1, 0px)');
+test_invalid_number('log(1, 0s)');
+test_invalid_number('log(1, 0deg)');
+test_invalid_number('log(1, 0Hz)');
+test_invalid_number('log(1, 0dpi)');
+test_invalid_number('log(1, 0fr)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/exp-log-serialize.html b/testing/web-platform/tests/css/css-values/exp-log-serialize.html
new file mode 100644
index 0000000000..9eca44e682
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/exp-log-serialize.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(t,s,c) {
+ test_specified_serialization('opacity', t, s);
+ test_specified_serialization('transform', `scale(${t})`, `scale(${s})`);
+ test_computed_serialization('opacity', t, c);
+ test_computed_serialization('transform', `scale(${t})`, `matrix(${c}, 0, 0, ${c}, 0, 0)`);
+}
+
+test_serialization(
+ 'exp(0)',
+ 'calc(1)',
+ '1');
+test_serialization(
+ 'log(1)',
+ 'calc(0)',
+ '0');
+
+test_serialization(
+ 'calc(exp(0) + log(1) + log(1))',
+ 'calc(1)',
+ '1');
+
+test_serialization(
+ 'calc(log(1) + 0.5)',
+ 'calc(0.5)',
+ '0.5');
+test_serialization(
+ 'calc(log(0))',
+ 'calc(-infinity)',
+ '-infinity');
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-001.html b/testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-001.html
new file mode 100644
index 0000000000..6f3ba3ac47
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-001.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values Test: mixed units in calc() and computed border-radius longhand and shorthand values (complex)</title>
+
+ <!--
+
+ Original test is:
+
+https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/getComputedStyle-border-radius.html
+
+
+ Bug 137688: getPropertyValue on computed style does not do shorthand properties
+ https://bugzilla.mozilla.org/show_bug.cgi?id=137688
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#calc-serialize">
+ <link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-border-radius">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <style>
+ div#target
+ {
+ border: solid 2px;
+ border-top-left-radius: calc(10px + 25%) calc(20px + 25%);
+ border-top-right-radius: calc(1em + 25%);
+ border-bottom-right-radius: calc(25%);
+ border-bottom-left-radius: calc(25px);
+ font-size: 16px; /* was 10px in original test */
+ height: 100px;
+ width: 100px;
+ }
+ </style>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function verifyComputedStyle(property_name, expected_value, description)
+ {
+
+ test(function()
+ {
+
+ assert_equals(getComputedStyle(targetElement)[property_name], expected_value);
+
+ }, description);
+ }
+
+ /* verifyComputedStyle(property_name, expected_value, description) */
+
+ verifyComputedStyle("border-top-left-radius", "calc(25% + 10px) calc(25% + 20px)", "testing border-top-left-radius: calc(10px + 25%) calc(20px + 25%)");
+
+ verifyComputedStyle("border-top-right-radius", "calc(25% + 16px)", "testing border-top-right-radius: calc(1em + 25%)");
+
+ verifyComputedStyle("border-bottom-right-radius", "25%", "testing border-bottom-right-radius: calc(25%)");
+
+ verifyComputedStyle("border-bottom-left-radius", "25px", "testing border-bottom-left-radius: calc(25px);");
+
+ verifyComputedStyle("border-radius", "calc(25% + 10px) calc(25% + 16px) 25% 25px / calc(25% + 20px) calc(25% + 16px) 25% 25px", "testing border-radius shorthand");
+
+ /*
+
+ The first value is the horizontal radius, the second the vertical radius.
+
+ horizontal radius / vertical radius
+ |__________________________________________| |__________________________________________|
+
+
+ The four values for each radii are given in the order top-left, top-right, bottom-right, bottom-left:
+
+
+ top-left top-right bottom-right bottom-left / top-left top-right bottom-right bottom-left
+
+ |__________________________________________| |__________________________________________|
+
+ horizontal radius / vertical radius
+
+ */
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-002.html b/testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-002.html
new file mode 100644
index 0000000000..8dec53f3f0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-002.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values Test: percentages in calc() and computed border-radius values</title>
+
+ <!--
+
+ Bugzilla bug report 1516454: Computed value of border-radius with calc(percentage) is incorrect
+ https://bugzilla.mozilla.org/show_bug.cgi?id=1516454
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#calc-computed-value">
+
+ <style>
+ div#target
+ {
+ border: black solid 5px;
+ height: 100px;
+ width: 100px;
+ }
+ </style>
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="log"></div>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function compareValue(property_name, calcValue, expectedValue, description)
+ {
+
+ test(function()
+ {
+
+ targetElement.style.setProperty(property_name, "initial");
+
+ targetElement.style.setProperty(property_name, calcValue);
+
+ var computedCalcValue = getComputedStyle(targetElement)[property_name];
+
+ targetElement.style.setProperty(property_name, expectedValue);
+
+ var computedExpectedValue = getComputedStyle(targetElement)[property_name];
+
+ assert_equals(computedCalcValue, computedExpectedValue);
+
+ }, description);
+ }
+
+ compareValue("border-top-left-radius", "calc(50%)", "50%", "simple percentage conversion test 1");
+
+ compareValue("border-top-right-radius", "calc(50%)", "50%", "simple percentage conversion test 2");
+
+ compareValue("border-bottom-left-radius", "calc(50%)", "50%", "simple percentage conversion test 3");
+
+ compareValue("border-bottom-right-radius", "calc(50%)", "50%", "simple percentage conversion test 4");
+
+ compareValue("border-top-left-radius", "calc(50%) calc(25%)", "50% 25%", "percentage conversion test 5");
+
+ compareValue("border-top-right-radius", "calc(50%) calc(25%)", "50% 25%", "percentage conversion test 6");
+
+ compareValue("border-bottom-left-radius", "calc(50%) calc(25%)", "50% 25%", "percentage conversion test 7");
+
+ compareValue("border-bottom-right-radius", "calc(50%) calc(25%)", "50% 25%", "percentage conversion test 8");
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-003.html b/testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-003.html
new file mode 100644
index 0000000000..98d320bca2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/getComputedStyle-border-radius-003.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values Test: mixed units in calc() and computed border-radius shorthand value (complex)</title>
+
+ <!--
+
+ Bug 137688: getPropertyValue on computed style does not do shorthand properties
+ https://bugzilla.mozilla.org/show_bug.cgi?id=137688
+
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#calc-serialize">
+ <link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-border-radius">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <style>
+ div#target
+ {
+ border: solid 2px;
+ border-top-left-radius: calc(1px + 1%) calc(5px + 5%);
+ border-top-right-radius: calc(2px + 2%) calc(6px + 6%);
+ border-bottom-right-radius: calc(3px + 3%) calc(7px + 7%);
+ border-bottom-left-radius: calc(4px + 4%) calc(8px + 8%);
+ height: 100px;
+ width: 100px;
+ }
+ </style>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function verifyComputedStyle(property_name, expected_value, description)
+ {
+
+ test(function()
+ {
+
+ assert_equals(getComputedStyle(targetElement)[property_name], expected_value);
+
+ }, description);
+ }
+
+ /* verifyComputedStyle(property_name, expected_value, description) */
+
+ verifyComputedStyle("border-radius", "calc(1% + 1px) calc(2% + 2px) calc(3% + 3px) calc(4% + 4px) / calc(5% + 5px) calc(6% + 6px) calc(7% + 7px) calc(8% + 8px)", "testing border-radius shorthand");
+
+ /*
+
+ The first value is the horizontal radius, the second the vertical radius.
+
+ horizontal radius / vertical radius
+ |__________________________________________| |__________________________________________|
+
+
+ The four values for each radii are given in the order top-left, top-right, bottom-right, bottom-left:
+
+
+ top-left top-right bottom-right bottom-left / top-left top-right bottom-right bottom-left
+
+ |__________________________________________| |__________________________________________|
+
+ horizontal radius / vertical radius
+
+ */
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/getComputedStyle-calc-mixed-units-001.html b/testing/web-platform/tests/css/css-values/getComputedStyle-calc-mixed-units-001.html
new file mode 100644
index 0000000000..c6fea70aae
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/getComputedStyle-calc-mixed-units-001.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values Test: computed value of 3 calc() values</title>
+
+
+ <!--
+ "
+ Where percentages are not resolved at computed-value time,
+ they are not resolved in math functions, e.g.
+ 'calc(100% - 100% + 1px)' resolves to 'calc(0% + 1px)', not to
+ '1px'. If there are special rules for computing percentages
+ in a value (e.g. the 'height' property), they apply whenever
+ a math function contains percentages.
+ "
+ § 10.11 Computed Value
+ https://www.w3.org/TR/css-values-4/#calc-computed-value
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#calc-computed-value">
+
+ <meta name="flags" content="">
+ <meta content="This test verifies that terms with a percentage unit that can not be resolved at computed-value time will require a calc() wrapper. A term with an em value, on the other hand, must be resolved at computed-value time and therefore must be absolutized to 'px'." name="assert">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <style>
+ html, body
+ {
+ font-size: 16px;
+ height: 570px;
+ }
+
+ div#target
+ {
+ background-color: yellow;
+ background-image: url("support/cat.png");
+ background-position: top center;
+ background-repeat: no-repeat;
+ background-size: 14% 50%; /* entirely arbitrary and random background-size values */
+ height: 200px;
+ }
+ </style>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function verifyComputedStyle(property_name, specified_value, expected_value, description)
+ {
+
+ test(function()
+ {
+
+ targetElement.style.setProperty(property_name, specified_value);
+
+ assert_equals(getComputedStyle(targetElement)[property_name], expected_value);
+
+ }, description);
+ }
+
+ verifyComputedStyle("background-size", "calc(67% - 54% + 4em)", "calc(13% + 64px)", "testing background-size: calc(67% - 54% + 4em)");
+
+ /*
+ "Where percentages are not resolved at computed-value time,
+ they are not resolved in math functions (...)"
+ https://www.w3.org/TR/css-values-4/#calc-serialize
+
+ Therefore here, the percentage is preserved and
+ a calc() wrapper must be used. The 4em term
+ must be resolved though.
+ */
+
+ verifyComputedStyle("background-position", "calc(100% - 100% + 20em)", "calc(0% + 320px) 50%", "testing background-position: calc(100% - 100% + 20em)");
+
+ /*
+ Here too, the percentage is preserved and
+ a calc() wrapper must be used. The 20em term
+ must be resolved though.
+ */
+
+
+ verifyComputedStyle("height", "calc(60% - 50% + 3em)", "105px", "testing height: calc(60% - 50% + 3em)");
+
+ /*
+
+ The height of the containing block of div#target is not auto.
+ So, such percentage can and must be resolved at
+ computed-value time.
+
+ 570px mult 10% == 57px
+
+ + 48px
+ ============
+ 105px
+
+ */
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/hypot-pow-sqrt-computed.html b/testing/web-platform/tests/css/css-values/hypot-pow-sqrt-computed.html
new file mode 100644
index 0000000000..3cc85a5230
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/hypot-pow-sqrt-computed.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<script>
+
+// Identity tests
+test_math_used('pow(1,1)', '1', {type:'integer'});
+test_math_used('sqrt(1)', '1', {type:'integer'});
+test_math_used('hypot(1)', '1', {type:'integer'});
+
+// Nestings
+test_math_used('sqrt(pow(1,1))', '1', {type:'integer'});
+test_math_used('hypot(pow(1, sqrt(1)))', '1', {type:'integer'});
+test_math_used('calc(hypot(pow((1 + sqrt(1)) / 2, sqrt(1))))', '1', {type:'integer'});
+
+// General calculations
+test_math_used('calc(100px * pow(2, pow(2, 2)))','1600px');
+test_math_used('calc(1px * pow(2, 3))', '8px')
+test_math_used('calc(100px * sqrt(100))', '1000px');
+test_math_used('calc(1px * pow(2, sqrt(100))', '1024px');
+test_math_used('hypot(3px, 4px)', '5px');
+test_math_used('hypot(3e+9px, 4e+9px)', '5e+9px');
+test_math_used('calc(100px * hypot(3, 4))', '500px');
+test_math_used('hypot(-5px)', '5px');
+test_math_used('calc(1px * hypot(-5))', '5px');
+test_math_used('calc(1px * hypot(10000))','10000px');
+test_math_used('calc(2px * sqrt(100000000))','20000px');
+test_math_used('calc(3px * pow(20, 4))', '480000px');
+test_math_used('calc(-2 * hypot(3px, 4px))', '-10px');
+test_math_used('hypot(0% + 3px, 0% + 4px)', '5px');
+test_math_used('hypot(0% + 772.333px)', 'calc(0% + 772.333px)');
+test_math_used('hypot(0% + 772.35px)', 'calc(0% + 772.35px)');
+test_math_used('hypot(0% + 600px, 0% + 800px)', '1000px');
+
+//Type checking hypot
+test_math_used('hypot(1px)', '1px');
+test_math_used('hypot(1cm)', '1cm');
+test_math_used('hypot(1mm)', '1mm');
+test_math_used('hypot(1Q)', '1Q');
+test_math_used('hypot(1in)', '1in');
+test_math_used('hypot(1pc)', '1pc');
+test_math_used('hypot(1pt)', '1pt');
+test_math_used('hypot(1em)', '1em');
+test_math_used('hypot(1ex)', '1ex');
+test_math_used('hypot(1ch)', '1ch');
+test_math_used('hypot(1rem)', '1rem');
+test_math_used('hypot(1vh)', '1vh');
+test_math_used('hypot(1vw)', '1vw');
+test_math_used('hypot(1vmin)', '1vmin');
+test_math_used('hypot(1vmax)', '1vmax');
+test_math_used('hypot(1s)', '1s', {type:'time'});
+test_math_used('hypot(1ms)', '1ms', {type:'time'});
+test_math_used('hypot(1deg)', '1deg', {type:'angle', approx:0.001});
+test_math_used('hypot(1grad)', '1grad', {type:'angle', approx:0.001});
+test_math_used('hypot(1rad)', '1rad', {type:'angle', approx:0.001});
+test_math_used('hypot(1turn)', '1turn', {type:'angle', approx:0.001});
+</script>
diff --git a/testing/web-platform/tests/css/css-values/hypot-pow-sqrt-invalid.html b/testing/web-platform/tests/css/css-values/hypot-pow-sqrt-invalid.html
new file mode 100644
index 0000000000..edb3138012
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/hypot-pow-sqrt-invalid.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_number(value) {
+ test_invalid_value('opacity', value);
+}
+function test_invalid_length(value) {
+ // 'letter-spacing' accepts <length> only, not <percentage> or any mixes.
+ test_invalid_value('letter-spacing', value);
+}
+
+// Syntax checking
+test_invalid_number('hypot()');
+test_invalid_number('hypot( )');
+test_invalid_number('hypot(,)');
+test_invalid_number('hypot(1, )');
+test_invalid_number('hypot(, 1)');
+test_invalid_number('hypot(1 + )');
+test_invalid_number('hypot(1 - )');
+test_invalid_number('hypot(1 * )');
+test_invalid_number('hypot(1 / )');
+test_invalid_number('hypot(1 2)');
+test_invalid_number('hypot(1, , 2)');
+test_invalid_number('sqrt()');
+test_invalid_number('sqrt( )');
+test_invalid_number('sqrt(,)');
+test_invalid_number('sqrt(1, )');
+test_invalid_number('sqrt(, 1)');
+test_invalid_number('sqrt(1 + )');
+test_invalid_number('sqrt(1 - )');
+test_invalid_number('sqrt(1 * )');
+test_invalid_number('sqrt(1 / )');
+test_invalid_number('sqrt(1 2)');
+test_invalid_number('sqrt(1, , 2)');
+test_invalid_number('sqrt(1, 2)');
+test_invalid_number('pow( )');
+test_invalid_number('pow(,)');
+test_invalid_number('pow(1, )');
+test_invalid_number('pow(, 1)');
+test_invalid_number('pow(1 + )');
+test_invalid_number('pow(1 - )');
+test_invalid_number('pow(1 * )');
+test_invalid_number('pow(1 / )');
+test_invalid_number('pow(1 2)');
+test_invalid_number('pow(1, , 2)');
+
+// General tests
+test_invalid_length('calc(1px * pow(1))');
+test_invalid_length('calc(1px * pow(2px, 3px))');
+test_invalid_length('calc(sqrt(100px)');
+test_invalid_length('hypot(2px, 40%)');
+test_invalid_length('hypot(2px, 3)');
+test_invalid_length('hypot(3, ,4)');
+test_invalid_length('hypot(1, 2)');
+test_invalid_length('calc(1px * pow(2 3))');
+test_invalid_length('hypot()');
+test_invalid_length('calc(pow(2))');
+test_invalid_length('pow())');
+test_invalid_length('pow(1, 2)');
+test_invalid_length('calc(sqrt())');
+test_invalid_length('calc(sqrt(100, 200))');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/hypot-pow-sqrt-serialize.html b/testing/web-platform/tests/css/css-values/hypot-pow-sqrt-serialize.html
new file mode 100644
index 0000000000..ab8c28cc59
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/hypot-pow-sqrt-serialize.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(t,s,c) {
+ test_specified_serialization('opacity', t, s);
+ test_specified_serialization('transform', `scale(${t})`, `scale(calc(${c}))`);
+ test_computed_serialization('opacity', t, c);
+ test_computed_serialization('transform', `scale(${t})`, `matrix(${c}, 0, 0, ${c}, 0, 0)`);
+}
+
+test_serialization(
+ 'pow(1,1)',
+ 'calc(1)',
+ '1');
+test_serialization(
+ 'hypot(1)',
+ 'calc(1)',
+ '1');
+test_serialization(
+ 'sqrt(1)',
+ 'calc(1)',
+ '1');
+
+test_serialization(
+ 'calc(pow(1,1) - 0.5)',
+ 'calc(0.5)',
+ '0.5');
+test_serialization(
+ 'calc(hypot(1) * 0.5)',
+ 'calc(0.5)',
+ '0.5');
+test_serialization(
+ 'calc(sqrt(1) - 1)',
+ 'calc(0)',
+ '0');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-001.html b/testing/web-platform/tests/css/css-values/ic-unit-001.html
new file mode 100644
index 0000000000..5045e0108e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-001.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ic unit</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<link rel="match" href="reference/ic-unit-001-ref.html">
+<meta name="assert" content="The ic unit is equal to the used advance measure of the 水 (CJK water ideograph, U+6C34) glyph found in the font used to render it.">
+<style>
+@font-face {
+ font-family: IcTestFullWidth;
+ src: url(resources/IcTestFullWidth.woff2);
+}
+
+span {
+ font: 20px IcTestFullWidth;
+ background: green;
+ color: green;
+ top: 0; bottom: 0;
+ position: absolute;
+}
+div {
+ font: 20px IcTestFullWidth;
+ background: red;
+ color: red;
+ position: relative;
+ height: 10ic;
+ width: 5ic;
+ float: left;
+}
+
+div + div {
+ width: auto;
+}
+
+div + div span {
+ width: 5ic;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div><span>水水水水水</span></div>
+ <div><span></span>水水水水水</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-002.html b/testing/web-platform/tests/css/css-values/ic-unit-002.html
new file mode 100644
index 0000000000..b514dba42f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-002.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: the ic unit in vertical orientation</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#block-flow">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#text-orientation">
+<link rel="match" href="reference/ic-unit-002-ref.html">
+<meta name="assert" content="In vertical upright, the ic unit is equal to the used vertical advance measure of the 水 (CJK water ideograph, U+6C34) glyph found in the font used to render it.">
+<style>
+@font-face {
+ font-family: IcTestFullWidth;
+ src: url(resources/IcTestFullWidth.woff2);
+}
+
+span {
+ font: 20px IcTestFullWidth;
+ background: green;
+ color: green;
+ left: 0; right: 0;
+ position: absolute;
+}
+
+div {
+ font: 20px IcTestFullWidth;
+ background: red;
+ color: red;
+ position: relative;
+ height: 5ic;
+ width: 10ic;
+ writing-mode: vertical-rl;
+ text-orientation: upright;
+}
+
+div + div {
+ height: auto;
+}
+
+div + div span {
+ height: 5ic;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div><span>水水水水水</span></div>
+ <div><span></span>水水水水水</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-003.html b/testing/web-platform/tests/css/css-values/ic-unit-003.html
new file mode 100644
index 0000000000..3513d9c646
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-003.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: the ic unit in vertical orientation</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#block-flow">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#text-orientation">
+<link rel="match" href="reference/ic-unit-002-ref.html">
+<meta name="assert" content="In vertical mixed, the ic unit is equal to the used vertical advance measure of the 水 (CJK water ideograph, U+6C34) glyph found in the font used to render it.">
+<style>
+@font-face {
+ font-family: IcTestFullWidth;
+ src: url(resources/IcTestFullWidth.woff2);
+}
+
+span {
+ font: 20px IcTestFullWidth;
+ background: green;
+ color: green;
+ left: 0; right: 0;
+ position: absolute;
+}
+
+div {
+ font: 20px IcTestFullWidth;
+ background: red;
+ color: red;
+ position: relative;
+ height: 5ic;
+ width: 10ic;
+ writing-mode: vertical-rl;
+ text-orientation: mixed;
+}
+
+div + div {
+ height: auto;
+}
+
+div + div span {
+ height: 5ic;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div><span>水水水水水</span></div>
+ <div><span></span>水水水水水</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-004.html b/testing/web-platform/tests/css/css-values/ic-unit-004.html
new file mode 100644
index 0000000000..64755c385c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-004.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: the ic unit in vertical orientation</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#block-flow">
+<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#text-orientation">
+<link rel="match" href="reference/ic-unit-001-ref.html">
+<meta name="assert" content="In vertical sideways, the ic unit is equal to the used horizontal advance measure of the 水 (CJK water ideograph, U+6C34) glyph found in the font used to render it.">
+<style>
+@font-face {
+ font-family: IcTestFullWidth;
+ src: url(resources/IcTestFullWidth.woff2);
+}
+
+span {
+ font: 20px IcTestFullWidth;
+ background: green;
+ color: green;
+ left: 0; right: 0;
+ position: absolute;
+}
+
+div {
+ font: 20px IcTestFullWidth;
+ background: red;
+ color: red;
+ position: relative;
+ height: 5ic;
+ width: 10ic;
+ writing-mode: vertical-rl;
+ text-orientation: sideways;
+}
+
+div + div {
+ height: auto;
+}
+
+div + div span {
+ height: 5ic;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div><span>水水水水水</span></div>
+ <div><span></span>水水水水水</div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-008.html b/testing/web-platform/tests/css/css-values/ic-unit-008.html
new file mode 100644
index 0000000000..f58c6b156f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-008.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ic unit in width (basic)</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#font-relative-lengths">
+ <link rel="match" href="reference/ic-unit-008-ref.html">
+
+ <meta name="assert" content="In this test, the ic unit is the advance width measure of the 水 (CJK water ideograph, U+6C34) glyph.">
+
+ <style>
+ @font-face
+ {
+ font-family: IcTestFullWidth;
+ src: url(resources/IcTestFullWidth.woff2);
+ }
+
+ div
+ {
+ float: left;
+ font-family: IcTestFullWidth;
+ font-size: 80px; /* arbitrary font size */
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 1.8em;
+ width: 5ic;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ clear: left;
+ color: orange;
+ line-height: 1.8; /* arbitrary line-height */
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same width</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <!--
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#27700;
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#x6C34;
+
+ -->
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-009.html b/testing/web-platform/tests/css/css-values/ic-unit-009.html
new file mode 100644
index 0000000000..ba7cbee38e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-009.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ic unit in height (basic)</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#font-relative-lengths">
+ <link rel="match" href="reference/ic-unit-009-ref.html">
+
+ <meta name="assert" content="In this test, the ic unit is the advance height measure of the 水 (CJK water ideograph, U+6C34) glyph.">
+
+ <style>
+ @font-face
+ {
+ font-family: IcTestFullWidth;
+ src: url(resources/IcTestFullWidth.woff2);
+ }
+
+ div
+ {
+ float: left;
+ font-family: IcTestFullWidth;
+ font-size: 80px; /* arbitrary font size */
+ writing-mode: vertical-rl;
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 5ic;
+ width: 1.8em;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ color: orange;
+ line-height: 1.8; /* arbitrary line-height */
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <!--
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#27700;
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#x6C34;
+
+ -->
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-010.html b/testing/web-platform/tests/css/css-values/ic-unit-010.html
new file mode 100644
index 0000000000..548f998b71
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-010.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ic unit in height with 'text-orientation: mixed'</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#font-relative-lengths">
+ <link rel="match" href="reference/ic-unit-009-ref.html">
+
+ <meta name="assert" content="In this test, the ic unit is the advance height measure of the 水 (CJK water ideograph, U+6C34) glyph.">
+
+ <style>
+ @font-face
+ {
+ font-family: IcTestFullWidth;
+ src: url(resources/IcTestFullWidth.woff2);
+ }
+
+ div
+ {
+ float: left;
+ font-family: IcTestFullWidth;
+ font-size: 80px; /* arbitrary font size */
+ text-orientation: mixed;
+ writing-mode: vertical-rl;
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 5ic;
+ width: 1.8em;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ color: orange;
+ line-height: 1.8; /* arbitrary line-height */
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <!--
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#27700;
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#x6C34;
+
+ -->
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-011.html b/testing/web-platform/tests/css/css-values/ic-unit-011.html
new file mode 100644
index 0000000000..849dbaca18
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-011.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ic unit in height with 'text-orientation: upright'</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#font-relative-lengths">
+ <link rel="match" href="reference/ic-unit-009-ref.html">
+
+ <meta name="assert" content="In this test, the ic unit is the advance height measure of the 水 (CJK water ideograph, U+6C34) glyph.">
+
+ <style>
+ @font-face
+ {
+ font-family: IcTestFullWidth;
+ src: url(resources/IcTestFullWidth.woff2);
+ }
+
+ div
+ {
+ float: left;
+ font-family: IcTestFullWidth;
+ font-size: 80px; /* arbitrary font size */
+ text-orientation: upright;
+ writing-mode: vertical-rl;
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 5ic;
+ width: 1.8em;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ color: orange;
+ line-height: 1.8; /* arbitrary line-height */
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <!--
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#27700;
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#x6C34;
+
+ -->
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-012.html b/testing/web-platform/tests/css/css-values/ic-unit-012.html
new file mode 100644
index 0000000000..e5d8027d17
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-012.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: ic unit in height with 'text-orientation: sideways'</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#font-relative-lengths">
+ <link rel="match" href="reference/ic-unit-012-ref.html">
+
+ <meta name="assert" content="In this test, the ic unit is the advance width measure of the 水 (CJK water ideograph, U+6C34) glyph.">
+
+ <style>
+ @font-face
+ {
+ font-family: IcTestFullWidth;
+ src: url(resources/IcTestFullWidth.woff2);
+ }
+
+ div
+ {
+ float: left;
+ font-family: IcTestFullWidth;
+ font-size: 80px; /* arbitrary font size */
+ text-orientation: sideways;
+ writing-mode: vertical-rl;
+ }
+
+ div#test-blue
+ {
+ background-color: blue;
+ height: 5ic;
+ width: 1.8em;
+ }
+
+ div#reference-orange
+ {
+ background-color: orange;
+ color: orange;
+ line-height: 1.8; /* arbitrary line-height */
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="test-blue"></div>
+
+ <div id="reference-orange">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <!--
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#27700;
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#x6C34;
+
+ -->
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-013.html b/testing/web-platform/tests/css/css-values/ic-unit-013.html
new file mode 100644
index 0000000000..ad55792d60
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-013.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ic unit</title>
+<link rel="author" title="Kiet Ho" href="mailto:tho22@apple.com">
+<link rel="help" href="https://www.w3.org/TR/css-values-4/#ic">
+<link rel="match" href="reference/ic-unit-013-ref.html">
+<meta name="assert" content="The ic unit is equal to 0em if the CJK water glyph's advance is 0.">
+<style>
+/* The following font contains the CJK water (U+6C34) glyph as a zero-width character. */
+@font-face {
+ font-family: IcTestZeroWidth;
+ src: url(resources/IcTestZeroWidth.woff2);
+}
+
+.test {
+ font: 20px IcTestZeroWidth;
+ width: calc(100px + 10ic);
+ height: 20px;
+ background: green;
+ margin-bottom: 10px;
+}
+
+.ref {
+ /* Each ic should be equal to 0px because the CJK water glyph in the font is zero-width. */
+ width: 100px;
+ height: 20px;
+ background: green;
+}
+</style>
+
+<p>The test passes if there are two green rectangles of equal length.</p>
+<div class="test"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-014.html b/testing/web-platform/tests/css/css-values/ic-unit-014.html
new file mode 100644
index 0000000000..70014d671d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-014.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ic unit</title>
+<link rel="author" title="Kiet Ho" href="mailto:tho22@apple.com">
+<link rel="help" href="https://www.w3.org/TR/css-values-4/#ic">
+<link rel="match" href="reference/ic-unit-014-ref.html">
+<meta name="assert" content="The ic unit is equal to 0.5em if the CJK water glyph's advance is 0.5em.">
+<style>
+/* The following font contains the CJK water (U+6C34) glyph as a rectangle box,
+ with the width being exactly half of its height. */
+@font-face {
+ font-family: IcTestHalfWidth;
+ src: url(resources/IcTestHalfWidth.woff2);
+}
+
+.test {
+ font-family: IcTestHalfWidth;
+ font-size: 20px;
+ width: calc(100px + 10ic);
+ height: 20px;
+ background: green;
+ margin-bottom: 10px;
+}
+
+.ref {
+ /*
+ Each ic is equal to 10px, the width of a CJK water glyph.
+ (its height is 20px, and its width is half the height).
+ The width of .test is then:
+ 100px + (10ic * 10px / ic) = 200px
+ */
+ width: 200px;
+ height: 20px;
+ background: green;
+}
+</style>
+
+<p>The test passes if there are two green rectangles of equal length.</p>
+<div class="test"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/ic-unit-015.html b/testing/web-platform/tests/css/css-values/ic-unit-015.html
new file mode 100644
index 0000000000..3be22ecc20
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ic-unit-015.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ic unit</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#ic">
+<link rel="match" href="reference/ch-unit-016-ref.html">
+<meta name="assert" content="The ic unit = used advance measure of the “水” (CJK water ideograph, U+6C34) glyph found in the font used to render it">
+<style>
+@font-face {
+ font-family: ASCIIonly;
+ src: local(Ahem), url("/fonts/Ahem.ttf");
+ unicode-range: U+0000-007F;
+}
+@font-face {
+ font-family: IcTestHalfWidth;
+ src: url("resources/IcTestHalfWidth.woff2");
+}
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+}
+.test {
+ width: calc(20px + 2ic);
+}
+.ref {
+ width: 100px;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<!-- ASCIIonly only supports basic ASCII, and therefore should NOT be used
+ to derive the size of the 'ic' unit, which should instead be based on the
+ U+6C34 ideograph in IcTestHalfWidth, which is 0.5em wide. -->
+<div class="test" style="font: 80px ASCIIonly, IcTestHalfWidth;"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/integer_interpolation_round_half_towards_positive_infinity_order.html b/testing/web-platform/tests/css/css-values/integer_interpolation_round_half_towards_positive_infinity_order.html
new file mode 100644
index 0000000000..60c439ebcf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/integer_interpolation_round_half_towards_positive_infinity_order.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>Testing if integer interpolation is rounded towards positive infinity</title>
+<link rel="author" title="Joonghun Park" href="pjh0718@gmail.com">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#combine-integers">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+
+#flex-container {
+ display: flex;
+ animation: anim-order 4s steps(4) forwards 1;
+ animation-delay: -1s;
+ animation-play-state: paused;
+}
+
+@keyframes anim-order {
+ from {
+ order: -2;
+ }
+
+ to {
+ order: 0;
+ }
+}
+
+</style>
+<div id="flex-container"></div>
+<script>
+var test_description = "Integer interpolation should be rounded towards positive infinity";
+test(
+ t => {
+ const container = document.getElementById("flex-container");
+ const order_value = Number.parseFloat(getComputedStyle(container).getPropertyValue('order'));
+
+ assert_equals(order_value, -1, "Interpolation result for order should be rounded towards positive infinity");
+ },
+ test_description
+);
+</script>
diff --git a/testing/web-platform/tests/css/css-values/integer_interpolation_round_half_towards_positive_infinity_z_index.html b/testing/web-platform/tests/css/css-values/integer_interpolation_round_half_towards_positive_infinity_z_index.html
new file mode 100644
index 0000000000..c9b042ccb8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/integer_interpolation_round_half_towards_positive_infinity_z_index.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>Testing if integer interpolation is rounded towards positive infinity</title>
+<link rel="author" title="Joonghun Park" href="pjh0718@gmail.com">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#combine-integers">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+
+#anim-target {
+ animation: anim-z 4s steps(4) forwards 1;
+ animation-delay: -1s;
+ animation-play-state: paused;
+}
+
+@keyframes anim-z {
+ from {
+ z-index: -2;
+ }
+
+ to {
+ z-index: 0;
+ }
+}
+
+</style>
+<div id="anim-target"></div>
+<script>
+var test_description = "Integer interpolation should be rounded towards positive infinity";
+test(
+ t => {
+ const target = document.getElementById("anim-target");
+ const z_index_value = Number.parseFloat(getComputedStyle(target).getPropertyValue('z-index'));
+
+ assert_equals(z_index_value, -1, "Interpolation result for z-index should be rounded towards positive infinity");
+ },
+ test_description
+);
+</script>
diff --git a/testing/web-platform/tests/css/css-values/lh-rlh-on-root-001.html b/testing/web-platform/tests/css/css-values/lh-rlh-on-root-001.html
new file mode 100644
index 0000000000..f269816699
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/lh-rlh-on-root-001.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: using lh and rlh units on the root element</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<style>
+#measure_me { position: absolute; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id=measure_me>&nbsp;</div>
+
+<script>
+ function get_root_font_size() {
+ return parseFloat(window.getComputedStyle(window.document.documentElement).fontSize);
+ }
+ function get_root_line_height() {
+ /* getComputedStyle returns the computed value (not the used value) for the line-height property,
+ and the computed value of line-height:normal is normal,
+ so we cannot just query the value fo the proerty directly on the root element.
+ However the height of an abspos that only contains a single character from the first available font
+ and doesn't have any ancestor that changes the font-size or line-height property
+ gives us an indirect way to measure the root line-height in px.
+ */
+ return parseFloat(window.getComputedStyle(document.getElementById("measure_me")).height);
+ }
+
+ window.document.documentElement.style="font-size: initial; line-height:initial;";
+ initial_f_s = get_root_font_size();
+ initial_l_h = get_root_line_height();
+
+ test(function() {
+ window.document.documentElement.style="font-size: 142px; line-height: 1lh;";
+ l_h = get_root_line_height();
+ assert_approx_equals( l_h, initial_l_h, 1, "the lh unit on the root element's line-height property uses font metrics corresponding to the initial values of the font or line-height properties");
+ }, "lh in line-height on root");
+
+ test(function() {
+ window.document.documentElement.style="font-size: 142px; line-height: 1rlh;";
+ l_h = get_root_line_height();
+ assert_approx_equals( l_h, initial_l_h, 1, "the rlh unit on the root element's line-height property uses font metrics corresponding to the initial values of the font or line-height properties");
+ }, "rlh in line-height on root");
+
+ test(function() {
+ window.document.documentElement.style="font-size: 1lh; line-height: 142px;";
+ f_s = get_root_font_size();
+ assert_approx_equals( f_s, initial_l_h, 1, "the lh unit on the root element's font-size property uses font metrics corresponding to the initial values of the font or line-height properties");
+ }, "lh in font-size on root");
+
+ test(function() {
+ window.document.documentElement.style="font-size: 1rlh; line-height: 142px;";
+ f_s = get_root_font_size();
+ assert_approx_equals( f_s, initial_l_h, 1, "the rlh unit on the root element's font-size property uses font metrics corresponding to the initial values of the font or line-height properties");
+
+ }, "rlh in font-size on root");
+
+
+ test(function() {
+ window.document.documentElement.style="font-size: 142px; line-height: 2lh;";
+ l_h = get_root_line_height();
+ assert_approx_equals( l_h, initial_l_h * 2, 1, "the lh unit on the root element's line-height property actually works as a unit and doesn't merely cause a fallback that doesn't take the number of units into account");
+ }, "2lh in line-height on root");
+
+ test(function() {
+ window.document.documentElement.style="font-size: 142px; line-height: 2rlh;";
+ l_h = get_root_line_height();
+ assert_approx_equals( l_h, initial_l_h * 2, 1, "the rlh unit on the root element's line-height property actually works as a unit and doesn't merely cause a fallback that doesn't take the number of units into account");
+ }, "2rlh in line-height on root");
+
+ test(function() {
+ window.document.documentElement.style="font-size: 2lh; line-height: 142px;";
+ f_s = get_root_font_size();
+ assert_approx_equals( f_s, initial_l_h * 2, 1, "the lh unit on the root element's font-size property actually works as a unit and doesn't merely cause a fallback that doesn't take the number of units into account");
+ }, "2lh in font-size on root");
+
+ test(function() {
+ window.document.documentElement.style="font-size: 2rlh; line-height: 142px;";
+ f_s = get_root_font_size();
+ assert_approx_equals( f_s, initial_l_h * 2, 1, "the rlh unit on the root element's font-size property actually works as a unit and doesn't merely cause a fallback that doesn't take the number of units into account");
+
+ }, "2rlh in font-size on root");
+
+ /*make the test result page readable again*/
+ window.document.documentElement.style="font-size: initial; line-height: initial;";
+</script>
diff --git a/testing/web-platform/tests/css/css-values/lh-unit-001.html b/testing/web-platform/tests/css/css-values/lh-unit-001.html
new file mode 100644
index 0000000000..f7a6fc9551
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/lh-unit-001.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: using lh in line-height</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The lh unit resolves against the parent when used in the line-height property.">
+<style>
+div {
+ font-size: 50px;
+ line-height: 1;
+ width: 100px;
+ height: 100px;
+ background: red;
+}
+aside {
+ background: green;
+ font-size: 42px; /* number doesn't matter, as long as it's neither 100 nor 50 */
+ line-height: 2lh;
+}
+
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+<div><aside>&nbsp;</aside></div>
diff --git a/testing/web-platform/tests/css/css-values/lh-unit-002.html b/testing/web-platform/tests/css/css-values/lh-unit-002.html
new file mode 100644
index 0000000000..316637a18a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/lh-unit-002.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: using lh in font-size</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="The lh unit resolves against the parent when used in the font-size property.">
+<style>
+div {
+ width: 100px;
+ height: 100px;
+ background: red;
+ line-height: 50px;
+}
+aside {
+ background: green;
+ height: 1em;
+ line-height: 42px; /* number doesn't matter, as long as it's neither 50 nor 100*/
+ font-size: 2lh;
+}
+
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+<div><aside>&nbsp;</aside></div>
diff --git a/testing/web-platform/tests/css/css-values/lh-unit-003.html b/testing/web-platform/tests/css/css-values/lh-unit-003.html
new file mode 100644
index 0000000000..e22a4b95b1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/lh-unit-003.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: lh depending on @font-face</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #lh {
+ font-family: customfont;
+ font-size: 20px;
+ width: 10lh;
+ }
+</style>
+<div id="lh">
+ X<br>
+ X<br>
+ X<br>
+ X<br>
+ X<br>
+ X<br>
+ X<br>
+ X<br>
+ X<br>
+ X
+</div>
+<script>
+ test(() => {
+ assert_equals(lh.offsetWidth, lh.offsetHeight);
+ }, "Line-height and lh before @font-face loads");
+
+ let original_size = lh.offsetHeight;
+
+ promise_test(async (t) => {
+ let custom_font = new FontFace("customfont", "url(/css/css-fonts/support/fonts/Rochester.otf)");
+ document.fonts.add(custom_font);
+ await document.fonts.load("20px customfont");
+ assert_not_equals(lh.offsetHeight, original_size,
+ "Test is useless if normal line-height is the same for both the web font and the fallback font");
+ assert_equals(lh.offsetWidth, lh.offsetHeight,
+ "lh and normal line-height both affected");
+ }, "Line-height and lh after @font-face loaded");
+</script>
diff --git a/testing/web-platform/tests/css/css-values/lh-unit-004.html b/testing/web-platform/tests/css/css-values/lh-unit-004.html
new file mode 100644
index 0000000000..eab4df97b4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/lh-unit-004.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test: lh not affected by &lt;select&gt; fixup</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#font-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ select {
+ line-height: 100px;
+ width: 5lh;
+ }
+</style>
+<select id="lh"></select>
+<script>
+ test(() => {
+ assert_equals(getComputedStyle(lh).width, "500px");
+ }, "lh must be relative to computed line-height before select element fixup");
+</script>
diff --git a/testing/web-platform/tests/css/css-values/line-break-ch-unit.html b/testing/web-platform/tests/css/css-values/line-break-ch-unit.html
new file mode 100644
index 0000000000..295b418f30
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/line-break-ch-unit.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<title>CSS Values and Units Test: Lines of the ch unit can fit the specified number of characters</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-3/#font-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+div {
+ font-family: monospace;
+ font-size: 10px;
+ line-height: 1;
+}
+</style>
+<body>
+ <div id=log></div>
+<script>
+(function() {
+ // Test that lines do not wrap for elements of the width of
+ // 'ch' unit that have the specified number of characters.
+ let container = document.body;
+ let should_fit = [];
+ for (let i = 3; i < 100; i++) {
+ let element = document.createElement('div');
+ element.style.width = `${i}ch`;
+ element.textContent = `0 ${'0'.repeat(i - 2)}`;
+ container.appendChild(element);
+ should_fit.push(element);
+ }
+
+ // When the number of characters is +1, it should wrap.
+ let should_wrap = [];
+ for (let i = 3; i < 100; i++) {
+ let element = document.createElement('div');
+ element.style.width = `${i}ch`;
+ element.textContent = `0 ${'0'.repeat(i - 1)}`;
+ container.appendChild(element);
+ should_wrap.push(element);
+ }
+
+ for (let element of should_fit) {
+ test(() => {
+ assert_approx_equals(element.offsetHeight, 10, 1);
+ }, `${element.style.width} should fit`);
+ }
+
+ for (let element of should_wrap) {
+ test(() => {
+ assert_approx_equals(element.offsetHeight, 20, 1);
+ }, `${element.style.width} should wrap`);
+ }
+})();
+</script>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/max-20-arguments.html b/testing/web-platform/tests/css/css-values/max-20-arguments.html
new file mode 100644
index 0000000000..9ed12875ac
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/max-20-arguments.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Values and Units Test: max() with 20 arguments</title>
+
+ <meta name="assert" content="UAs must support math function expressions of at least 20 terms.">
+ <link rel="author" title="Fuqiao Xue" href="mailto:xfq@w3.org">
+ <link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-syntax">
+ <link rel="match" href="reference/all-green.html">
+
+ <style>
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; overflow: hidden; }
+ #outer { position: absolute; top: 0px; left: 0px; background: green; width: 100%; }
+
+ #outer { height: max(5%, 10%, 15%, 20%, 25%, 30%, 35%, 40%, 45%, 50%, 55%, 60%, 65%, 70%, 75%, 80%, 85%, 90%, 95%, 100%); }
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/max-length-percent-001.html b/testing/web-platform/tests/css/css-values/max-length-percent-001.html
new file mode 100644
index 0000000000..6d1e9ed248
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/max-length-percent-001.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS values: max() between pixel and percentage values</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="match" href="reference/200-200-green.html">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<style>
+html, body { margin: 0px; padding: 0px; }
+#parent { width: 400px; }
+#target {
+ width: max(100px, 25% + 100px, 150px + 10%);
+ height: 200px;
+ background: green;
+}
+#fail {
+ width: 200px;
+ height: 200px;
+ position: absolute;
+ z-index: -1;
+ background: red;
+}
+</style>
+<div id=parent>
+ <div id=fail></div>
+ <div id=target></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-values/max-unitless-zero-invalid.html b/testing/web-platform/tests/css/css-values/max-unitless-zero-invalid.html
new file mode 100644
index 0000000000..5f06d6a2bc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/max-unitless-zero-invalid.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>CSS Values and Units Test: min() with unitless 0</title>
+
+ <meta name="assert" content="Unitless 0 isn't supported in math functions.">
+ <link rel="author" title="Fuqiao Xue" href="mailto:xfq@w3.org">
+ <link rel="help" href="https://drafts.csswg.org/css-values/#calc-type-checking">
+ <link rel="match" href="reference/all-green.html">
+
+ <style>
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; overflow: hidden; }
+ #outer { position: absolute; top: 0px; left: 0px; background: green; width: 100%; }
+
+ #outer {
+ /* Assert that min() is supported */
+ height: min(100%);
+
+ /* The min() expression (thus the declaration) should be invalid */
+ height: min(0, 100%);
+ }
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/min-length-percent-001.html b/testing/web-platform/tests/css/css-values/min-length-percent-001.html
new file mode 100644
index 0000000000..0ffceb827a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/min-length-percent-001.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS values: min() between pixel and percentage values</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="match" href="reference/200-200-green.html">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<style>
+html, body { margin: 0px; padding: 0px; }
+#parent { width: 400px; }
+#target {
+ width: min(300px, 25% + 100px, 50px + 50%);
+ height: 200px;
+ background: green;
+}
+#fail {
+ width: 200px;
+ height: 200px;
+ position: absolute;
+ z-index: -1;
+ background: red;
+}
+</style>
+<div id=parent>
+ <div id=fail></div>
+ <div id=target></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-values/min-max-percentage-length-interpolation.html b/testing/web-platform/tests/css/css-values/min-max-percentage-length-interpolation.html
new file mode 100644
index 0000000000..089d6f0407
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/min-max-percentage-length-interpolation.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<title>Tests interpolation between CSS comparison functions</title>
+<style>
+@keyframes anim {
+ from {
+ width: min(50px, 30%);
+ height: min(75%, 160px);
+ }
+ to {
+ width: max(75%, 100px);
+ height: max(50px, 20%);
+ }
+}
+
+.test {
+ background-color: green;
+ animation: anim 1s linear;
+ animation-delay: -.5s;
+ animation-play-state: paused;
+}
+
+.fail {
+ background: red;
+ position: absolute;
+ z-index: -1;
+ width: 100px;
+ height: 100px;
+}
+
+.container {
+ position: absolute;
+ width: 200px;
+ height: 200px;
+}
+</style>
+<p>Test passes if there is a filled green square.</p>
+<div class="container">
+ <div class="fail"></div>
+ <div class="test"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-values/minmax-angle-computed.html b/testing/web-platform/tests/css/css-values/minmax-angle-computed.html
new file mode 100644
index 0000000000..2c14aa6576
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-angle-computed.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#angles">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<div id="reference"></div>
+<script>
+function test_angle_equals(value, expected) {
+ test_math_used(`rotate(${value})`, `rotate(${expected})`,
+ {prop:'transform', base:'none',
+ msg: `${value} should be used-value-equivalent to ${expected}`});
+}
+
+// Identity tests
+test_angle_equals('min(1deg)', '1deg');
+test_angle_equals('min(1grad)', '1grad');
+test_angle_equals('min(1rad)', '1rad');
+test_angle_equals('min(1turn)', '1turn');
+test_angle_equals('max(1deg)', '1deg');
+test_angle_equals('max(1grad)', '1grad');
+test_angle_equals('max(1rad)', '1rad');
+test_angle_equals('max(1turn)', '1turn');
+
+// Comparisons between same units
+test_angle_equals('min(1deg, 2deg)', '1deg');
+test_angle_equals('min(1grad, 2grad)', '1grad');
+test_angle_equals('min(1rad, 2rad)', '1rad');
+test_angle_equals('min(1turn, 2turn)', '1turn');
+test_angle_equals('max(1deg, 2deg)', '2deg');
+test_angle_equals('max(1grad, 2grad)', '2grad');
+test_angle_equals('max(1rad, 2rad)', '2rad');
+test_angle_equals('max(1turn, 2turn)', '2turn');
+
+// Comparisons between different units
+test_angle_equals('min(90deg, 0.26turn)', '90deg');
+test_angle_equals('min(1.57rad, 95deg)', '1.57rad');
+test_angle_equals('max(91deg, 0.25turn)', '91deg');
+test_angle_equals('max(1.58rad, 90deg)', '1.58rad');
+
+// Nestings
+test_angle_equals('min(270deg, max(0.25turn, 3.14rad))', '3.14rad');
+test_angle_equals('max(0.25turn, min(270deg, 3.14rad))', '3.14rad');
+
+// General calculations
+test_angle_equals('calc(min(90deg, 1.58rad) + 0.125turn)', '135deg');
+test_angle_equals('calc(min(90deg, 1.58rad) - 0.125turn)', '45deg');
+test_angle_equals('calc(min(90deg, 1.58rad) * 1.5', '135deg');
+test_angle_equals('calc(min(90deg, 1.58rad) / 2', '45deg');
+test_angle_equals('calc(max(90deg, 1.56rad) + 0.125turn', '135deg');
+test_angle_equals('calc(max(90deg, 1.56rad) - 0.125turn)', '45deg');
+test_angle_equals('calc(max(90deg, 1.56rad) * 1.5', '135deg');
+test_angle_equals('calc(max(90deg, 1.56rad) / 2', '45deg');
+test_angle_equals('calc(min(90deg, 1.58rad) + max(0.125turn, 49grad))', '135deg');
+test_angle_equals('calc(min(90deg, 1.58rad) - max(0.25turn, 99grad))', '0deg');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-angle-invalid.html b/testing/web-platform/tests/css/css-values/minmax-angle-invalid.html
new file mode 100644
index 0000000000..29dc15dfd9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-angle-invalid.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#angles">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_angle(value) {
+ test_invalid_value('transform', `rotate(${value})`);
+}
+
+// Syntax checking
+test_invalid_angle('min()');
+test_invalid_angle('min( )');
+test_invalid_angle('min(,)');
+test_invalid_angle('min(1dag)');
+test_invalid_angle('min(1deg, )');
+test_invalid_angle('min(, 1deg)');
+test_invalid_angle('min(1deg + )');
+test_invalid_angle('min(1deg - )');
+test_invalid_angle('min(1deg * )');
+test_invalid_angle('min(1deg / )');
+test_invalid_angle('min(1deg 2deg)');
+test_invalid_angle('min(1deg, , 2deg)');
+test_invalid_angle('max()');
+test_invalid_angle('max( )');
+test_invalid_angle('max(,)');
+test_invalid_angle('max(1dag)');
+test_invalid_angle('max(1deg, )');
+test_invalid_angle('max(, 1deg)');
+test_invalid_angle('max(1deg + )');
+test_invalid_angle('max(1deg - )');
+test_invalid_angle('max(1deg * )');
+test_invalid_angle('max(1deg / )');
+test_invalid_angle('max(1deg 2deg)');
+test_invalid_angle('max(1deg, , 2deg)');
+
+// Type checking
+test_invalid_angle('min(0)');
+test_invalid_angle('min(0%)');
+test_invalid_angle('min(0px)');
+test_invalid_angle('min(0s)');
+test_invalid_angle('min(0Hz)');
+test_invalid_angle('min(0dpi)');
+test_invalid_angle('min(0fr)');
+test_invalid_angle('min(1deg, 0)');
+test_invalid_angle('min(1deg, 0%)');
+test_invalid_angle('min(1deg, 0px)');
+test_invalid_angle('min(1deg, 0s)');
+test_invalid_angle('min(1deg, 0Hz)');
+test_invalid_angle('min(1deg, 0dpi)');
+test_invalid_angle('min(1deg, 0fr)');
+test_invalid_angle('max(0)');
+test_invalid_angle('max(0%)');
+test_invalid_angle('max(0px)');
+test_invalid_angle('max(0s)');
+test_invalid_angle('max(0Hz)');
+test_invalid_angle('max(0dpi)');
+test_invalid_angle('max(0fr)');
+test_invalid_angle('max(1deg, 0)');
+test_invalid_angle('max(1deg, 0%)');
+test_invalid_angle('max(1deg, 0px)');
+test_invalid_angle('max(1deg, 0s)');
+test_invalid_angle('max(1deg, 0Hz)');
+test_invalid_angle('max(1deg, 0dpi)');
+test_invalid_angle('max(1deg, 0fr)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-angle-serialize.html b/testing/web-platform/tests/css/css-values/minmax-angle-serialize.html
new file mode 100644
index 0000000000..106d6d2411
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-angle-serialize.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#angles">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="author" title="Tab Atkins-Bittner" href="https://xanthir.com/contact">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(t,s,c,u, {prop="transform"}={}) {
+ t = `rotate(${t})`;
+ test_specified_serialization(prop, t, `rotate(${s})`);
+ test_computed_serialization(prop, t, c);
+ if(u) test_used_serialization(prop, t, u);
+}
+
+// Browsers aren't perfectly interoperable about how a 90deg rotation is serialized,
+// but that's not the focus of this test,
+// so just capture *whatever* the browser does and expect that.
+const rotateMatrix = (()=>{
+ const el = document.querySelector("#target");
+ el.style.transform = "rotate(90deg)";
+ const ret = getComputedStyle(el).transform;
+ el.removeAttribute('style');
+ return ret;
+})();
+
+test_serialization(
+ 'min(90deg)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'min(.25turn)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'min(100grad)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'max(90deg)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'max(.25turn)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'max(100grad)',
+ 'calc(90deg)',
+ rotateMatrix);
+// No way to test 'rad' serialization without depending heavily on numeric serialization
+// and the precision used for radians...
+
+test_serialization(
+ 'min(90deg, 92deg, 93deg)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'min(93deg, 92deg, 90deg)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'min(90deg, 1.58rad, 0.25turn)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'min(0.25turn, 1.58rad, 90deg)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'max(81deg, 82deg, 90deg)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'max(83deg, 82deg, 90deg)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'max(90deg, 1.57rad, 0.25turn)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'max(0.25turn, 1.57rad, 90deg)',
+ 'calc(90deg)',
+ rotateMatrix);
+
+test_serialization(
+ 'calc(min(30deg) + max(60deg))',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'calc(50grad + min(45deg))',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'calc(min(45deg) + 50grad)',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'calc(50grad + max(45deg))',
+ 'calc(90deg)',
+ rotateMatrix);
+test_serialization(
+ 'calc(max(45deg) + 50grad)',
+ 'calc(90deg)',
+ rotateMatrix);
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-integer-computed.html b/testing/web-platform/tests/css/css-values/minmax-integer-computed.html
new file mode 100644
index 0000000000..49dbe198c9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-integer-computed.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#integers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-range">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<script>
+function test_integer_equals(value, expected) {
+ test_math_used(value, expected,
+ {base: '123',
+ prop: 'z-index'}
+ );
+}
+
+// Identity tests
+test_integer_equals('min(1)', '1');
+test_integer_equals('max(1)', '1');
+
+// Rounding
+test_integer_equals('min(0.4)', '0');
+test_integer_equals('min(0.6)', '1');
+test_integer_equals('max(0.4)', '0');
+test_integer_equals('max(0.6)', '1');
+
+// Rounding and nesting
+test_integer_equals('min(1.1, max(0.4, 0.6))', '1');
+test_integer_equals('max(0.3, min(1.1, 0.4))', '0');
+
+// No rounding at intermediate steps
+test_integer_equals('calc(min(0.3, 0.6) * 2)', '1');
+test_integer_equals('calc(max(0.3, 0.6) / 2)', '0');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-length-computed.html b/testing/web-platform/tests/css/css-values/minmax-length-computed.html
new file mode 100644
index 0000000000..096a272a31
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-length-computed.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#lengths">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="container" style="font-size: 20px">
+ <div id="target"></div>
+</div>
+<script>
+const property = 'letter-spacing';
+
+function test_length_equals(value, expected, msgExtra) {
+ test_math_used(value, expected, {msgExtra});
+}
+
+// Identity tests
+test_length_equals('min(1px)', '1px');
+test_length_equals('min(1cm)', '1cm');
+test_length_equals('min(1mm)', '1mm');
+test_length_equals('min(1Q)', '1Q');
+test_length_equals('min(1in)', '1in');
+test_length_equals('min(1pc)', '1pc');
+test_length_equals('min(1pt)', '1pt');
+test_length_equals('min(1em)', '1em');
+test_length_equals('min(1ex)', '1ex');
+test_length_equals('min(1ch)', '1ch');
+test_length_equals('min(1rem)', '1rem');
+test_length_equals('min(1vh)', '1vh');
+test_length_equals('min(1vw)', '1vw');
+test_length_equals('min(1vmin)', '1vmin');
+test_length_equals('min(1vmax)', '1vmax');
+test_length_equals('max(1px)', '1px');
+test_length_equals('max(1cm)', '1cm');
+test_length_equals('max(1mm)', '1mm');
+test_length_equals('max(1Q)', '1Q');
+test_length_equals('max(1in)', '1in');
+test_length_equals('max(1pc)', '1pc');
+test_length_equals('max(1pt)', '1pt');
+test_length_equals('max(1em)', '1em');
+test_length_equals('max(1ex)', '1ex');
+test_length_equals('max(1ch)', '1ch');
+test_length_equals('max(1rem)', '1rem');
+test_length_equals('max(1vh)', '1vh');
+test_length_equals('max(1vw)', '1vw');
+test_length_equals('max(1vmin)', '1vmin');
+test_length_equals('max(1vmax)', '1vmax');
+
+// Comparisons between same units
+test_length_equals('min(1px, 2px)', '1px');
+test_length_equals('min(1cm, 2cm)', '1cm');
+test_length_equals('min(1mm, 2mm)', '1mm');
+test_length_equals('min(1Q, 2Q)', '1Q');
+test_length_equals('min(1in, 2in)', '1in');
+test_length_equals('min(1pc, 2pc)', '1pc');
+test_length_equals('min(1pt, 2pt)', '1pt');
+test_length_equals('min(1em, 2em)', '1em');
+test_length_equals('min(1ex, 2ex)', '1ex');
+test_length_equals('min(1ch, 2ch)', '1ch');
+test_length_equals('min(1rem, 2rem)', '1rem');
+test_length_equals('min(1vh, 2vh)', '1vh');
+test_length_equals('min(1vw, 2vw)', '1vw');
+test_length_equals('min(1vmin, 2vmin)', '1vmin');
+test_length_equals('min(1vmax, 2vmax)', '1vmax');
+test_length_equals('max(1px, 2px)', '2px');
+test_length_equals('max(1cm, 2cm)', '2cm');
+test_length_equals('max(1mm, 2mm)', '2mm');
+test_length_equals('max(1Q, 2Q)', '2Q');
+test_length_equals('max(1in, 2in)', '2in');
+test_length_equals('max(1pc, 2pc)', '2pc');
+test_length_equals('max(1pt, 2pt)', '2pt');
+test_length_equals('max(1em, 2em)', '2em');
+test_length_equals('max(1ex, 2ex)', '2ex');
+test_length_equals('max(1ch, 2ch)', '2ch');
+test_length_equals('max(1rem, 2rem)', '2rem');
+test_length_equals('max(1vh, 2vh)', '2vh');
+test_length_equals('max(1vw, 2vw)', '2vw');
+test_length_equals('max(1vmin, 2vmin)', '2vmin');
+test_length_equals('max(1vmax, 2vmax)', '2vmax');
+
+// Comparisons between different absolute units
+test_length_equals('min(95px, 1in)', '95px');
+test_length_equals('max(95px, 1in)', '1in');
+
+// Comparisons between absolute and relative units
+test_length_equals('min(15px, 1em)', '15px');
+test_length_equals('min(25px, 1em)', '20px');
+test_length_equals('max(15px, 1em)', '20px');
+test_length_equals('max(25px, 1em)', '25px');
+
+document.getElementById('container').style.fontSize = '10px';
+test_length_equals('min(15px, 1em)', '10px', 'fontSize=10px');
+test_length_equals('max(15px, 2em)', '20px', 'fontSize=10px');
+
+document.getElementById('container').style.fontSize = '20px';
+
+// Nestings
+test_length_equals('min(25px, max(15px, 1em))', '20px');
+test_length_equals('max(15px, min(25px, 1em))', '20px');
+
+// General calculations
+test_length_equals('calc(min(1em, 21px) + 10px)', '30px');
+test_length_equals('calc(min(1em, 21px) - 10px)', '10px');
+test_length_equals('calc(min(1em, 21px) * 2', '40px');
+test_length_equals('calc(min(1em, 21px) / 2', '10px');
+test_length_equals('calc(max(1em, 19px) + 10px)', '30px');
+test_length_equals('calc(max(1em, 19px) - 10px)', '10px');
+test_length_equals('calc(max(1em, 19px) * 2', '40px');
+test_length_equals('calc(max(1em, 19px) / 2', '10px');
+test_length_equals('calc(min(1em, 21px) + max(0.9em, 20px))', '40px');
+test_length_equals('calc(min(1em + 1px, 22px) - max(0.9em, 20px))', '1px');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-length-invalid.html b/testing/web-platform/tests/css/css-values/minmax-length-invalid.html
new file mode 100644
index 0000000000..1405c31981
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-length-invalid.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#lengths">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_length(value) {
+ // 'letter-spacing' accepts <length> only, not <percentage> or any mixes.
+ test_invalid_value('letter-spacing', value);
+}
+
+// Syntax checking
+test_invalid_length('min()');
+test_invalid_length('min( )');
+test_invalid_length('min(,)');
+test_invalid_length('min(1py)');
+test_invalid_length('min(1px, )');
+test_invalid_length('min(, 1px)');
+test_invalid_length('min(1px + )');
+test_invalid_length('min(1px - )');
+test_invalid_length('min(1px * )');
+test_invalid_length('min(1px / )');
+test_invalid_length('min(1px 2px)');
+test_invalid_length('min(1px, , 2px)');
+test_invalid_length('max()');
+test_invalid_length('max( )');
+test_invalid_length('max(,)');
+test_invalid_length('max(1py)');
+test_invalid_length('max(1px, )');
+test_invalid_length('max(, 1px)');
+test_invalid_length('max(1px + )');
+test_invalid_length('max(1px - )');
+test_invalid_length('max(1px * )');
+test_invalid_length('max(1px / )');
+test_invalid_length('max(1px 2px)');
+test_invalid_length('max(1px, , 2px)');
+
+// Type checking
+test_invalid_length('min(0)');
+test_invalid_length('min(0%)');
+test_invalid_length('min(0s)');
+test_invalid_length('min(0Hz)');
+test_invalid_length('min(0dpi)');
+test_invalid_length('min(0fr)');
+test_invalid_length('min(1px, 0)');
+test_invalid_length('min(1px, 0%)');
+test_invalid_length('min(1px, 0s)');
+test_invalid_length('min(1px, 0Hz)');
+test_invalid_length('min(1px, 0dpi)');
+test_invalid_length('min(1px, 0fr)');
+test_invalid_length('max(0)');
+test_invalid_length('max(0%)');
+test_invalid_length('max(0s)');
+test_invalid_length('max(0Hz)');
+test_invalid_length('max(0dpi)');
+test_invalid_length('max(0fr)');
+test_invalid_length('max(1px, 0)');
+test_invalid_length('max(1px, 0%)');
+test_invalid_length('max(1px, 0s)');
+test_invalid_length('max(1px, 0Hz)');
+test_invalid_length('max(1px, 0dpi)');
+test_invalid_length('max(1px, 0fr)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-length-percent-computed.html b/testing/web-platform/tests/css/css-values/minmax-length-percent-computed.html
new file mode 100644
index 0000000000..9788fa26df
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-length-percent-computed.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#mixed-percentages">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="container" style="font-size: 20px; width: 400px">
+ <div id="target"></div>
+</div>
+<script>
+
+// Identity tests
+test_math_used('min(1px + 1%)', 'calc(1px + 1%)', {prop:'margin-left'});
+test_math_used('min(1cm + 1%)', 'calc(1cm + 1%)');
+test_math_used('min(1mm + 1%)', 'calc(1mm + 1%)');
+test_math_used('min(1Q + 1%)', 'calc(1Q + 1%)');
+test_math_used('min(1in + 1%)', 'calc(1in + 1%)');
+test_math_used('min(1pc + 1%)', 'calc(1pc + 1%)');
+test_math_used('min(1pt + 1%)', 'calc(1pt + 1%)');
+test_math_used('min(1em + 1%)', 'calc(1em + 1%)');
+test_math_used('min(1ex + 1%)', 'calc(1ex + 1%)');
+test_math_used('min(1ch + 1%)', 'calc(1ch + 1%)');
+test_math_used('min(1rem + 1%)', 'calc(1rem + 1%)');
+test_math_used('min(1vh + 1%)', 'calc(1vh + 1%)');
+test_math_used('min(1vw + 1%)', 'calc(1vw + 1%)');
+test_math_used('min(1vmin + 1%)', 'calc(1vmin + 1%)');
+test_math_used('min(1vmax + 1%)', 'calc(1vmax + 1%)');
+test_math_used('max(1px + 1%)', 'calc(1px + 1%)');
+test_math_used('max(1cm + 1%)', 'calc(1cm + 1%)');
+test_math_used('max(1mm + 1%)', 'calc(1mm + 1%)');
+test_math_used('max(1Q + 1%)', 'calc(1Q + 1%)');
+test_math_used('max(1in + 1%)', 'calc(1in + 1%)');
+test_math_used('max(1pc + 1%)', 'calc(1pc + 1%)');
+test_math_used('max(1pt + 1%)', 'calc(1pt + 1%)');
+test_math_used('max(1em + 1%)', 'calc(1em + 1%)');
+test_math_used('max(1ex + 1%)', 'calc(1ex + 1%)');
+test_math_used('max(1ch + 1%)', 'calc(1ch + 1%)');
+test_math_used('max(1rem + 1%)', 'calc(1rem + 1%)');
+test_math_used('max(1vh + 1%)', 'calc(1vh + 1%)');
+test_math_used('max(1vw + 1%)', 'calc(1vw + 1%)');
+test_math_used('max(1vmin + 1%)', 'calc(1vmin + 1%)');
+test_math_used('max(1vmax + 1%)', 'calc(1vmax + 1%)');
+
+// Comparisons between lengths and percentages
+test_math_used('min(20px, 10%)', '20px');
+test_math_used('min(1em, 10%)', '20px');
+test_math_used('max(20px, 10%)', '40px');
+test_math_used('max(1em, 10%)', '40px');
+
+document.getElementById('container').style.width = '100px';
+test_math_used('min(20px, 10%)', '10px', {msgExtra:'width=100px'});
+test_math_used('min(1em, 10%)', '10px', {msgExtra:'width=100px'});
+test_math_used('max(20px, 10%)', '20px', {msgExtra:'width=100px'});
+test_math_used('max(1em, 10%)', '20px', {msgExtra:'width=100px'});
+document.getElementById('container').style.width = '400px';
+
+// Comparisons between different mixings
+test_math_used('min(30px + 10%, 60px + 5%)', '70px');
+test_math_used('max(2em + 10%, 1em + 20%)', '100px');
+
+// General calculations
+test_math_used('calc(min(1.5em, 10%) + 10px)', '40px');
+test_math_used('calc(min(1.5em, 10%) - 10px)', '20px');
+test_math_used('calc(min(1.5em, 10%) * 2)', '60px');
+test_math_used('calc(min(1.5em, 10%) / 2)', '15px');
+test_math_used('calc(max(1em, 15%) + 10px)', '70px');
+test_math_used('calc(max(1em, 15%) - 10px)', '50px');
+test_math_used('calc(max(1em, 15%) * 2)', '120px');
+test_math_used('calc(max(1em, 15%) / 2)', '30px');
+test_math_used('calc(min(1.5em, 10%) + max(1em, 15%))', '90px');
+test_math_used('calc(min(1.5em, 10%) - max(1em, 15%))', '-30px');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-length-percent-invalid.html b/testing/web-platform/tests/css/css-values/minmax-length-percent-invalid.html
new file mode 100644
index 0000000000..ee086ef269
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-length-percent-invalid.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#mixed-percentages">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_length_percent(value) {
+ test_invalid_value('margin-left', value);
+}
+
+// Type checking only. Syntax checking is done by other test files.
+// <length-percentage> accepts mixing lengths and percentages only.
+test_invalid_length_percent('min(1px, 0)');
+test_invalid_length_percent('min(1px, 0s)');
+test_invalid_length_percent('min(1px, 0Hz)');
+test_invalid_length_percent('min(1px, 0dpi)');
+test_invalid_length_percent('min(1px, 0fr)');
+test_invalid_length_percent('min(1%, 0)');
+test_invalid_length_percent('min(1%, 0s)');
+test_invalid_length_percent('min(1%, 0Hz)');
+test_invalid_length_percent('min(1%, 0dpi)');
+test_invalid_length_percent('min(1%, 0fr)');
+test_invalid_length_percent('max(1px, 0)');
+test_invalid_length_percent('max(1px, 0s)');
+test_invalid_length_percent('max(1px, 0Hz)');
+test_invalid_length_percent('max(1px, 0dpi)');
+test_invalid_length_percent('max(1px, 0fr)');
+test_invalid_length_percent('max(1%, 0)');
+test_invalid_length_percent('max(1%, 0s)');
+test_invalid_length_percent('max(1%, 0Hz)');
+test_invalid_length_percent('max(1%, 0dpi)');
+test_invalid_length_percent('max(1%, 0fr)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-length-percent-serialize.html b/testing/web-platform/tests/css/css-values/minmax-length-percent-serialize.html
new file mode 100644
index 0000000000..43d2806658
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-length-percent-serialize.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#mixed-percentages">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="author" title="Tab Atkins-Bittner" href="https://xanthir.com/contact">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div style="width: 100px;">
+ <div id=target></div>
+</div>
+<script>
+function test_serialization(t,s,c,u, {prop}={}) {
+ test_specified_serialization(prop || 'text-indent', t, s);
+ test_computed_serialization(prop || 'text-indent', t, c);
+ if(u) test_used_serialization(prop || 'margin-left', t, u);
+}
+
+// If fully resolvable to a number, serialize to a calc() or all the way to a number.
+test_serialization(
+ 'min(1px)',
+ 'calc(1px)',
+ '1px',
+ '1px');
+test_serialization(
+ 'max(1px)',
+ 'calc(1px)',
+ '1px',
+ '1px');
+
+// If not, keep as the function.
+test_serialization(
+ 'min(1% + 1px)',
+ 'calc(1% + 1px)',
+ 'calc(1% + 1px)',
+ '2px');
+test_serialization(
+ 'min(1px + 1%)',
+ 'calc(1% + 1px)',
+ 'calc(1% + 1px)',
+ '2px');
+test_serialization(
+ 'max(1px + 1%)',
+ 'calc(1% + 1px)',
+ 'calc(1% + 1px)',
+ '2px');
+
+// Arguments are simplified eagerly as per spec:
+test_serialization(
+ 'min(1px, 2px)',
+ 'calc(1px)',
+ '1px',
+ '1px');
+
+// Arguments are simplified, but not reordered.
+test_serialization(
+ 'min(20px, 10%)',
+ 'min(20px, 10%)',
+ 'min(20px, 10%)',
+ '10px');
+test_serialization(
+ 'min(1em, 10%)',
+ 'min(1em, 10%)',
+ 'min(16px, 10%)',
+ '10px');
+test_serialization(
+ 'min(10%, 20px)',
+ 'min(10%, 20px)',
+ 'min(10%, 20px)',
+ '10px');
+test_serialization(
+ 'min(10%, 1em)',
+ 'min(10%, 1em)',
+ 'min(10%, 16px)',
+ '10px');
+test_serialization(
+ 'max(20px, 10%)',
+ 'max(20px, 10%)',
+ 'max(20px, 10%)',
+ '20px');
+test_serialization(
+ 'max(1em, 10%)',
+ 'max(1em, 10%)',
+ 'max(16px, 10%)',
+ '16px');
+test_serialization(
+ 'max(10%, 20px)',
+ 'max(10%, 20px)',
+ 'max(10%, 20px)',
+ '20px');
+test_serialization(
+ 'max(10%, 1em)',
+ 'max(10%, 1em)',
+ 'max(10%, 16px)',
+ '16px');
+
+// Within an argument, normal sorting occurs
+test_serialization(
+ 'min(10% + 30px, 5em + 5%)',
+ 'min(10% + 30px, 5% + 5em)',
+ 'min(10% + 30px, 5% + 80px)',
+ '40px');
+test_serialization(
+ 'max(10% + 30px, 5em + 5%)',
+ 'max(10% + 30px, 5% + 5em)',
+ 'max(10% + 30px, 5% + 80px)',
+ '85px');
+
+// min()/max() are valid inside a calc(),
+// and retain their relative order
+test_serialization(
+ 'calc(min(10% + 1px) + max(1em + 10%) + min(10% + 20px))',
+ 'calc(30% + 1em + 21px)',
+ 'calc(30% + 37px)',
+ '67px');
+
+// min()/max() can be combined with plain units as well.
+// While min()/max() maintain their own ordering,
+// ordinary units will re-sort around them.
+test_serialization(
+ 'calc(1em + max(10% + 20px) + 5% + min(1em + 10%) + 10px)',
+ 'calc(25% + 2em + 30px)',
+ 'calc(25% + 62px)',
+ '87px');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-length-serialize.html b/testing/web-platform/tests/css/css-values/minmax-length-serialize.html
new file mode 100644
index 0000000000..bd00ee0588
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-length-serialize.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#lengths">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div style="width: 100px;">
+ <div id=target></div>
+</div>
+<script>
+function test_serialization(t,s,c,u, {prop}={}) {
+ test_specified_serialization(prop || 'text-indent', t, s);
+ test_computed_serialization(prop || 'text-indent', t, c);
+ if(u) test_used_serialization(prop || 'margin-left', t, u);
+}
+
+test_serialization(
+ 'min(1px)',
+ 'calc(1px)',
+ '1px');
+test_serialization(
+ 'min(1in)',
+ 'calc(96px)',
+ '96px');
+test_serialization(
+ 'max(1px)',
+ 'calc(1px)',
+ '1px');
+test_serialization(
+ 'max(1in)',
+ 'calc(96px)',
+ '96px');
+
+// Values are case-insensitive and serialize as lower case, for example 1Q
+// serializes as 1q.
+test_serialization(
+ 'min(1PX)',
+ 'calc(1px)',
+ '1px');
+
+// Arguments simplify down eagerly
+test_serialization(
+ 'min(50px, 1in + 1px)',
+ 'calc(50px)',
+ '50px');
+test_serialization(
+ 'max(50px, 1in + 1px)',
+ 'calc(97px)',
+ '97px');
+
+// And the entire function simplifies eagerly if possible
+test_serialization(
+ 'calc(1px + min(1in, 100px))',
+ 'calc(97px)',
+ '97px');
+test_serialization(
+ 'calc(1px + max(1in, 100px))',
+ 'calc(101px)',
+ '101px');
+
+// Computed-value units preserve min()/max() in specified values
+test_serialization(
+ 'min(1px, 1em)',
+ 'min(1px, 1em)',
+ '1px');
+test_serialization(
+ 'calc(min(1px, 1in) + max(100px + 1em, 10px + 1in) + 1px)',
+ 'calc(2px + max(1em + 100px, 106px))',
+ '118px');
+
+// Can't test that min()/max() are preserved in computed values with just lengths;
+// see minmax-length-percentage-serialize for tests of that.
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-number-computed.html b/testing/web-platform/tests/css/css-values/minmax-number-computed.html
new file mode 100644
index 0000000000..3a1c609e16
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-number-computed.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<script>
+// Identity tests
+test_math_used('min(1)', '1', {type:'number'});
+test_math_used('max(1)', '1', {type:'number'});
+
+// Nestings
+test_math_used('min(0.2, max(0.1, 0.15))', '0.15', {type:'number'});
+test_math_used('max(0.1, min(0.2, 0.15))', '0.15', {type:'number'});
+
+// General calculations
+test_math_used('calc(min(0.1, 0.2) + 0.05)', '0.15', {type:'number'});
+test_math_used('calc(min(0.1, 0.2) - 0.05)', '0.05', {type:'number'});
+test_math_used('calc(min(0.1, 0.2) * 2)', '0.2', {type:'number'});
+test_math_used('calc(min(0.1, 0.2) / 2)', '0.05', {type:'number'});
+test_math_used('calc(max(0.1, 0.2) + 0.05)', '0.25', {type:'number'});
+test_math_used('calc(max(0.1, 0.2) - 0.05)', '0.15', {type:'number'});
+test_math_used('calc(max(0.1, 0.2) * 2)', '0.4', {type:'number'});
+test_math_used('calc(max(0.1, 0.2) / 2)', '0.1', {type:'number'});
+test_math_used('calc(min(0.1, 0.2) + max(0.1, 0.05))', '0.2', {type:'number'});
+test_math_used('calc(min(0.1, 0.2) - max(0.1, 0.05))', '0', {type:'number'});
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-number-invalid.html b/testing/web-platform/tests/css/css-values/minmax-number-invalid.html
new file mode 100644
index 0000000000..3f34fde2f2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-number-invalid.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_number(value) {
+ test_invalid_value('opacity', value);
+}
+
+// Syntax checking
+test_invalid_number('min()');
+test_invalid_number('min( )');
+test_invalid_number('min(,)');
+test_invalid_number('min(1, )');
+test_invalid_number('min(, 1)');
+test_invalid_number('min(1 + )');
+test_invalid_number('min(1 - )');
+test_invalid_number('min(1 * )');
+test_invalid_number('min(1 / )');
+test_invalid_number('min(1 2)');
+test_invalid_number('min(1, , 2)');
+test_invalid_number('max()');
+test_invalid_number('max( )');
+test_invalid_number('max(,)');
+test_invalid_number('max(1, )');
+test_invalid_number('max(, 1)');
+test_invalid_number('max(1 + )');
+test_invalid_number('max(1 - )');
+test_invalid_number('max(1 * )');
+test_invalid_number('max(1 / )');
+test_invalid_number('max(1 2)');
+test_invalid_number('max(1, , 2)');
+
+// Type checking
+test_invalid_number('min(0px)');
+test_invalid_number('min(0s)');
+test_invalid_number('min(0deg)');
+test_invalid_number('min(0Hz)');
+test_invalid_number('min(0dpi)');
+test_invalid_number('min(0fr)');
+test_invalid_number('min(1, 1%)');
+test_invalid_number('min(1, 0px)');
+test_invalid_number('min(1, 0s)');
+test_invalid_number('min(1, 0deg)');
+test_invalid_number('min(1, 0Hz)');
+test_invalid_number('min(1, 0dpi)');
+test_invalid_number('min(1, 0fr)');
+test_invalid_number('max(0px)');
+test_invalid_number('max(0s)');
+test_invalid_number('max(0deg)');
+test_invalid_number('max(0Hz)');
+test_invalid_number('max(0dpi)');
+test_invalid_number('max(0fr)');
+test_invalid_number('max(1, 1%)');
+test_invalid_number('max(1, 0px)');
+test_invalid_number('max(1, 0s)');
+test_invalid_number('max(1, 0deg)');
+test_invalid_number('max(1, 0Hz)');
+test_invalid_number('max(1, 0dpi)');
+test_invalid_number('max(1, 0fr)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-number-serialize.html b/testing/web-platform/tests/css/css-values/minmax-number-serialize.html
new file mode 100644
index 0000000000..fc34f19983
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-number-serialize.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="author" title="Tab Atkins-Bittner" href="https://xanthir.com/contact">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(t,s,c) {
+ test_specified_serialization('opacity', t, s);
+ test_specified_serialization('transform', `scale(${t})`, `scale(calc(${c}))`);
+ test_computed_serialization('opacity', t, c);
+ test_computed_serialization('transform', `scale(${t})`, `matrix(${c}, 0, 0, ${c}, 0, 0)`);
+}
+
+test_serialization(
+ 'min(.1)',
+ 'calc(0.1)',
+ '0.1');
+test_serialization(
+ 'max(.1)',
+ 'calc(0.1)',
+ '0.1');
+
+test_serialization(
+ 'min(.1, .2, .3)',
+ 'calc(0.1)',
+ '0.1');
+test_serialization(
+ 'max(.1, .2, .3)',
+ 'calc(0.3)',
+ '0.3');
+
+test_serialization(
+ 'min(.3, .2, .1)',
+ 'calc(0.1)',
+ '0.1');
+test_serialization(
+ 'max(.3, .2, .1)',
+ 'calc(0.3)',
+ '0.3');
+
+test_serialization(
+ 'calc(min(.1) + min(.2))',
+ 'calc(0.3)',
+ '0.3');
+test_serialization(
+ 'calc(max(.1) + max(.2))',
+ 'calc(0.3)',
+ '0.3');
+
+test_serialization(
+ 'calc(.1 + min(.1))',
+ 'calc(0.2)',
+ '0.2');
+test_serialization(
+ 'calc(max(.1) + .1)',
+ 'calc(0.2)',
+ '0.2');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-percentage-computed.html b/testing/web-platform/tests/css/css-values/minmax-percentage-computed.html
new file mode 100644
index 0000000000..fbdad71fcd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-percentage-computed.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#percentages">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="container" style="width: 400px">
+ <div id="target"></div>
+</div>
+<script>
+
+// Identity tests
+test_math_used('min(1%)', '1%');
+test_math_used('max(1%)', '1%');
+
+// Nestings
+test_math_used('min(20%, max(10%, 15%))', '15%');
+test_math_used('max(10%, min(20%, 15%))', '15%');
+
+// General calculations
+test_math_used('calc(min(10%, 20%) + 5%)', '15%');
+test_math_used('calc(min(10%, 20%) - 5%)', '5%');
+test_math_used('calc(min(10%, 20%) * 2)', '20%');
+test_math_used('calc(min(10%, 20%) / 2)', '5%');
+test_math_used('calc(max(10%, 20%) + 5%)', '25%');
+test_math_used('calc(max(10%, 20%) - 5%)', '15%');
+test_math_used('calc(max(10%, 20%) * 2)', '40%');
+test_math_used('calc(max(10%, 20%) / 2)', '10%');
+test_math_used('calc(min(10%, 20%) + max(10%, 5%))', '20%');
+test_math_used('calc(min(11%, 20%) - max(10%, 5%))', '1%');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-percentage-invalid.html b/testing/web-platform/tests/css/css-values/minmax-percentage-invalid.html
new file mode 100644
index 0000000000..48d2cdabec
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-percentage-invalid.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#percentages">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_percentage(value) {
+ test_invalid_value('margin-left', value);
+}
+
+// Syntax checking
+test_invalid_percentage('min()');
+test_invalid_percentage('min( )');
+test_invalid_percentage('min(,)');
+test_invalid_percentage('min(1#)');
+test_invalid_percentage('min(%1)');
+test_invalid_percentage('min(1%, )');
+test_invalid_percentage('min(, 1%)');
+test_invalid_percentage('min(1% + )');
+test_invalid_percentage('min(1% - )');
+test_invalid_percentage('min(1% * )');
+test_invalid_percentage('min(1% / )');
+test_invalid_percentage('min(1% 2%)');
+test_invalid_percentage('min(1%, , 2%)');
+test_invalid_percentage('max()');
+test_invalid_percentage('max( )');
+test_invalid_percentage('max(,)');
+test_invalid_percentage('max(1#)');
+test_invalid_percentage('max(%1)');
+test_invalid_percentage('max(1%, )');
+test_invalid_percentage('max(, 1%)');
+test_invalid_percentage('max(1% + )');
+test_invalid_percentage('max(1% - )');
+test_invalid_percentage('max(1% * )');
+test_invalid_percentage('max(1% / )');
+test_invalid_percentage('max(1% 2%)');
+test_invalid_percentage('max(1%, , 2%)');
+
+// Type checking
+test_invalid_percentage('min(0s)');
+test_invalid_percentage('min(0deg)');
+test_invalid_percentage('min(0Hz)');
+test_invalid_percentage('min(0dpi)');
+test_invalid_percentage('min(0fr)');
+test_invalid_percentage('min(1%, 0)');
+test_invalid_percentage('min(1%, 0s)');
+test_invalid_percentage('min(1%, 0deg)');
+test_invalid_percentage('min(1%, 0Hz)');
+test_invalid_percentage('min(1%, 0dpi)');
+test_invalid_percentage('min(1%, 0fr)');
+test_invalid_percentage('max(0s)');
+test_invalid_percentage('max(0deg)');
+test_invalid_percentage('max(0Hz)');
+test_invalid_percentage('max(0dpi)');
+test_invalid_percentage('max(0fr)');
+test_invalid_percentage('max(1%, 0)');
+test_invalid_percentage('max(1%, 0s)');
+test_invalid_percentage('max(1%, 0deg)');
+test_invalid_percentage('max(1%, 0Hz)');
+test_invalid_percentage('max(1%, 0dpi)');
+test_invalid_percentage('max(1%, 0fr)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-percentage-serialize.html b/testing/web-platform/tests/css/css-values/minmax-percentage-serialize.html
new file mode 100644
index 0000000000..65ab9fad96
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-percentage-serialize.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#percentages">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="author" title="Tab Atkins-Bittner" href="https://xanthir.com/contact">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div style="width: 100px;">
+ <div id=target></div>
+</div>
+<script>
+function test_serialization(t,s,c,u, {prop}={}) {
+ test_specified_serialization(prop || 'text-indent', t,s);
+ test_computed_serialization(prop || 'text-indent', t,c);
+ if(u) test_used_serialization(prop || 'margin-left', t,u);
+}
+
+test_serialization(
+ 'min(1%)',
+ 'calc(1%)',
+ '1%',
+ '1px');
+test_serialization(
+ 'max(1%)',
+ 'calc(1%)',
+ '1%',
+ '1px');
+
+
+// %s can't be simplified until we resolve them,
+// since in some cases they can resolve against a negative value
+// (so that 20% is less than 10%),
+// and we don't want to try and distinguish between the properties
+// where the resolving value is possibly-negative or always non-negative.
+test_serialization(
+ 'min(1%, 2%, 3%)',
+ 'min(1%, 2%, 3%)',
+ 'min(1%, 2%, 3%)',
+ '1px');
+test_serialization(
+ 'min(3%, 2%, 1%)',
+ 'min(3%, 2%, 1%)',
+ 'min(3%, 2%, 1%)',
+ '1px');
+test_serialization(
+ 'max(1%, 2%, 3%)',
+ 'max(1%, 2%, 3%)',
+ 'max(1%, 2%, 3%)',
+ '3px');
+test_serialization(
+ 'max(3%, 2%, 1%)',
+ 'max(3%, 2%, 1%)',
+ 'max(3%, 2%, 1%)',
+ '3px');
+
+// Also ensure that this works against a possibly-negative resolving value...
+test_serialization(
+ 'min(1%, 2%, 3%) 0px',
+ 'min(1%, 2%, 3%) 0px',
+ 'min(1%, 2%, 3%) 0px',
+ '',
+ {prop:'background-position'});
+
+test_serialization(
+ 'calc(min(1%, 2%) + max(3%, 4%) + 10%)',
+ 'calc(10% + min(1%, 2%) + max(3%, 4%))',
+ 'calc(10% + min(1%, 2%) + max(3%, 4%))',
+ '15px');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-time-computed.html b/testing/web-platform/tests/css/css-values/minmax-time-computed.html
new file mode 100644
index 0000000000..c6a708f028
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-time-computed.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#time">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<script>
+function test_time_equals(t,e) {
+ test_math_used(t, e, {type:"time"});
+}
+
+// Identity tests
+test_time_equals('min(1s)', '1s');
+test_time_equals('min(1ms)', '1ms');
+test_time_equals('max(1s)', '1s');
+test_time_equals('max(1ms)', '1ms');
+
+// Comparisons between same units
+test_time_equals('min(1s, 2s)', '1s');
+test_time_equals('min(1ms, 2ms)', '1ms');
+test_time_equals('max(1s, 2s)', '2s');
+test_time_equals('max(1ms, 2ms)', '2ms');
+
+// Comparisons between different units
+test_time_equals('min(1s, 1100ms)', '1s');
+test_time_equals('max(0.9s, 1000ms)', '1000ms');
+
+// Nestings
+test_time_equals('min(2s, max(1s, 1500ms))', '1500ms');
+test_time_equals('max(1000ms, min(2000ms, 1.5s))', '1.5s');
+
+// General calculations
+test_time_equals('calc(min(0.5s, 600ms) + 500ms)', '1s');
+test_time_equals('calc(min(0.6s, 700ms) - 500ms)', '0.1s');
+test_time_equals('calc(min(0.5s, 600ms) * 2)', '1s');
+test_time_equals('calc(min(0.5s, 600ms) / 2)', '0.25s');
+test_time_equals('calc(max(0.5s, 400ms) + 500ms)', '1s');
+test_time_equals('calc(max(0.5s, 400ms) - 400ms)', '0.1s');
+test_time_equals('calc(max(0.5s, 400ms) * 2)', '1s');
+test_time_equals('calc(max(0.5s, 400ms) / 2)', '0.25s');
+test_time_equals('calc(min(0.5s, 600ms) + max(500ms, 0.4s))', '1s');
+test_time_equals('calc(min(0.6s, 700ms) - max(500ms, 0.4s))', '0.1s');
+test_time_equals('min(1s + 100ms, 500ms * 3)', '1.1s');
+test_time_equals('calc(min(1s, 2s) + max(3s, 4s) + 10s)', '15s');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-time-invalid.html b/testing/web-platform/tests/css/css-values/minmax-time-invalid.html
new file mode 100644
index 0000000000..bebe674cd7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-time-invalid.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#time">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_time(value) {
+ test_invalid_value('transition-delay', value);
+}
+
+// Syntax checking
+test_invalid_time('min()');
+test_invalid_time('min( )');
+test_invalid_time('min(,)');
+test_invalid_time('min(1mt)');
+test_invalid_time('min(1s, )');
+test_invalid_time('min(, 1s)');
+test_invalid_time('min(1s + )');
+test_invalid_time('min(1s - )');
+test_invalid_time('min(1s * )');
+test_invalid_time('min(1s / )');
+test_invalid_time('min(1s 2s)');
+test_invalid_time('min(1s, , 2s)');
+test_invalid_time('max()');
+test_invalid_time('max( )');
+test_invalid_time('max(,)');
+test_invalid_time('max(1dag)');
+test_invalid_time('max(1s, )');
+test_invalid_time('max(, 1s)');
+test_invalid_time('max(1s + )');
+test_invalid_time('max(1s - )');
+test_invalid_time('max(1s * )');
+test_invalid_time('max(1s / )');
+test_invalid_time('max(1s 2s)');
+test_invalid_time('max(1s, , 2s)');
+
+// Type checking
+test_invalid_time('min(0)');
+test_invalid_time('min(0%)');
+test_invalid_time('min(0px)');
+test_invalid_time('min(0deg)');
+test_invalid_time('min(0Hz)');
+test_invalid_time('min(0dpi)');
+test_invalid_time('min(0fr)');
+test_invalid_time('min(1s, 0)');
+test_invalid_time('min(1s, 0%)');
+test_invalid_time('min(1s, 0px)');
+test_invalid_time('min(1s, 0deg)');
+test_invalid_time('min(1s, 0Hz)');
+test_invalid_time('min(1s, 0dpi)');
+test_invalid_time('min(1s, 0fr)');
+test_invalid_time('max(0)');
+test_invalid_time('max(0%)');
+test_invalid_time('max(0px)');
+test_invalid_time('max(0deg)');
+test_invalid_time('max(0Hz)');
+test_invalid_time('max(0dpi)');
+test_invalid_time('max(0fr)');
+test_invalid_time('max(1s, 0)');
+test_invalid_time('max(1s, 0%)');
+test_invalid_time('max(1s, 0px)');
+test_invalid_time('max(1s, 0deg)');
+test_invalid_time('max(1s, 0Hz)');
+test_invalid_time('max(1s, 0dpi)');
+test_invalid_time('max(1s, 0fr)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/minmax-time-serialize.html b/testing/web-platform/tests/css/css-values/minmax-time-serialize.html
new file mode 100644
index 0000000000..27d09cfa28
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/minmax-time-serialize.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#time">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="author" title="Tab Atkins-Bittner" href="https://xanthir.com/contact">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(t,s,c,u, {prop="transition-delay"}={}) {
+ test_specified_serialization(prop, t, s);
+ test_computed_serialization(prop, t, c);
+ if(u) test_used_serialization(prop, t, u);
+}
+
+test_serialization(
+ 'min(1ms)',
+ 'calc(0.001s)',
+ '0.001s');
+test_serialization(
+ 'min(1s)',
+ 'calc(1s)',
+ '1s');
+test_serialization(
+ 'max(1ms)',
+ 'calc(0.001s)',
+ '0.001s');
+test_serialization(
+ 'max(1s)',
+ 'calc(1s)',
+ '1s');
+
+test_serialization(
+ 'min(1s, 2s, 3s)',
+ 'calc(1s)',
+ '1s');
+test_serialization(
+ 'min(3s, 2s, 1s)',
+ 'calc(1s)',
+ '1s');
+test_serialization(
+ 'max(1s, 2s, 3s)',
+ 'calc(3s)',
+ '3s');
+test_serialization(
+ 'max(3s, 2s, 1s)',
+ 'calc(3s)',
+ '3s');
+test_serialization(
+ 'min(900ms, 1s)',
+ 'calc(0.9s)',
+ '0.9s');
+test_serialization(
+ 'max(1100ms, 1s)',
+ 'calc(1.1s)',
+ '1.1s');
+
+test_serialization(
+ 'calc(min(1s, 2s) + max(3s, 4s) + 10s)',
+ 'calc(15s)',
+ '15s');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/negative-calc-to-non-negative-integer-ref.html b/testing/web-platform/tests/css/css-values/negative-calc-to-non-negative-integer-ref.html
new file mode 100644
index 0000000000..4468091607
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/negative-calc-to-non-negative-integer-ref.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<title>CSS Test reference</title>
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<style>
+@counter-style foo {
+ system: additive;
+ additive-symbols: 1 'I', 0 'X';
+ range: infinite infinite;
+}
+</style>
+<ol style="list-style-type: foo" start=-1>
+<li></li>
+<li></li>
+<li></li>
+</ol>
diff --git a/testing/web-platform/tests/css/css-values/negative-calc-to-non-negative-integer.html b/testing/web-platform/tests/css/css-values/negative-calc-to-non-negative-integer.html
new file mode 100644
index 0000000000..b38cb759ad
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/negative-calc-to-non-negative-integer.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-range">
+<link rel="help" href="https://drafts.csswg.org/css-counter-styles/#the-counter-style-rule">
+<link rel="match" href="negative-calc-to-non-negative-integer-ref.html">
+<meta name="assert" content="Negative calc() passed to <non-negative-integer> property value as argument should be addressed properly.">
+<style>
+@counter-style foo {
+ system: additive;
+ additive-symbols: 1 'I', calc(-1) 'X';
+ range: infinite infinite;
+}
+</style>
+<ol style="list-style-type: foo" start=-1>
+<li></li>
+<li></li>
+<li></li>
+</ol>
diff --git a/testing/web-platform/tests/css/css-values/percentage-rem-low.html b/testing/web-platform/tests/css/css-values/percentage-rem-low.html
new file mode 100644
index 0000000000..d06e7522a6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/percentage-rem-low.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>REM value with :root set to low percentage</title>
+<link rel="author" title="Jon Ege Ronnenberg" href="mailto:jon.ronnenberg+wpt@gmail.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#rem">
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#length-percentage-size-value">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<meta name="assert" content="When :root font-size is 25%, a 25rem length must be 100px, if the browser default for :root font-size is 16px.">
+<style>
+ :root {
+ /* default is 16px in all desktop browsers */
+ /* the math for 100px is: 16px * 0.25 = 4px/rem -> 100px / 4px/rem = 25rem = 100px */
+ font-size: 25%;
+ }
+ .rem {
+ width: 25rem;
+ height: 25rem;
+ background-color: green;
+ }
+</style>
+<p style="font-size:initial;">Test passes if there is a filled green square.</p>
+<div class="rem"></div>
diff --git a/testing/web-platform/tests/css/css-values/q-unit-case-insensitivity-001.html b/testing/web-platform/tests/css/css-values/q-unit-case-insensitivity-001.html
new file mode 100644
index 0000000000..6fb548766a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/q-unit-case-insensitivity-001.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: case-insensitivity of Q unit (quarter-millimeter)</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#absolute-lengths">
+ <link rel="help" href="https://www.w3.org/TR/CSS22/syndata.html#characters">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <meta content="This test checks that 'Q' unit is case-insensitive." name="assert">
+
+ <style>
+ div#test-overlapping-green
+ {
+ background-color: green;
+ height: 105.83333Q;
+ width: 1px;
+ width: 105.83333q;
+ }
+
+ /*
+
+ 25.4mm == 96px
+ Therefore, 26.45833mm == 100px
+ So, 26.45833 * 4 (Q per mm) == 105.83333Q == 100px
+
+ */
+
+ div#reference-overlapped-red
+ {
+ background-color: red;
+ bottom: 100px;
+ height: 100px;
+ position: relative;
+ width: 100px;
+ z-index: -1;
+ }
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="test-overlapping-green"></div>
+
+ <div id="reference-overlapped-red"></div>
diff --git a/testing/web-platform/tests/css/css-values/q-unit-case-insensitivity-002.html b/testing/web-platform/tests/css/css-values/q-unit-case-insensitivity-002.html
new file mode 100644
index 0000000000..e0eb5239d8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/q-unit-case-insensitivity-002.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: case-insensitivity of Q unit (quarter-millimeter)</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-values-3/#absolute-lengths">
+ <link rel="help" href="https://www.w3.org/TR/CSS22/syndata.html#characters">
+ <link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+
+ <meta content="This test checks that 'Q' unit is case-insensitive." name="assert">
+
+ <style>
+ div#test-overlapping-green
+ {
+ background-color: green;
+ height: 105.83333q;
+ width: 1px;
+ width: 105.83333Q;
+ }
+
+ /*
+
+ 25.4mm == 96px
+ Therefore, 26.45833mm == 100px
+ So, 26.45833 * 4 (Q per mm) == 105.83333Q == 100px
+
+ */
+
+ div#reference-overlapped-red
+ {
+ background-color: red;
+ bottom: 100px;
+ height: 100px;
+ position: relative;
+ width: 100px;
+ z-index: -1;
+ }
+ </style>
+
+ <p>Test passes if there is a filled green square and <strong>no red</strong>.
+
+ <div id="test-overlapping-green"></div>
+
+ <div id="reference-overlapped-red"></div>
diff --git a/testing/web-platform/tests/css/css-values/rch-invalidation.html b/testing/web-platform/tests/css/css-values/rch-invalidation.html
new file mode 100644
index 0000000000..fa85e94c72
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/rch-invalidation.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>CSS Values and Units Test: rch invalidation</title>
+<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#font-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="assert" content="test rch invalidation">
+<style>
+ @import url("/fonts/ahem.css");
+ html {
+ font-family: 'Ahem';
+ font-size: 40px;
+ }
+ body {
+ font-family: monospace;
+ font-size: 20px;
+ }
+ div {
+ width: 10rch;
+ }
+</style>
+
+<html>
+ <body>
+ <div id="div"></div>
+ </body>
+</html>
+
+<script>
+ setup({ single_test: true });
+ let old_width = div.getBoundingClientRect().width;
+ document.documentElement.style.fontFamily = "sans-serif";
+ let new_width = div.getBoundingClientRect().width;
+ assert_not_equals(old_width, new_width, "expect the width of zero of Ahem and sans-serif to be different");
+ done();
+</script>
diff --git a/testing/web-platform/tests/css/css-values/reference/200-200-green.html b/testing/web-platform/tests/css/css-values/reference/200-200-green.html
new file mode 100644
index 0000000000..f3da3ddb3b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/200-200-green.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewport units are interpolated correctly (reference rendering)
+ </title>
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: white; overflow: hidden; }
+ #outer { position: relative; background: green; }
+
+ #outer { width: 200px; height: 200px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/reference/all-green.html b/testing/web-platform/tests/css/css-values/reference/all-green.html
new file mode 100644
index 0000000000..c70532129a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/all-green.html
@@ -0,0 +1 @@
+<html style="background: green"></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/reference/cap-unit-001-ref.html b/testing/web-platform/tests/css/css-values/reference/cap-unit-001-ref.html
new file mode 100644
index 0000000000..b1816deb43
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/cap-unit-001-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units reference: support for the cap unit</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<style>
+div {
+ background: green;
+ height: 100px;
+ width: 100px;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/reference/ch-unit-001-ref.html b/testing/web-platform/tests/css/css-values/reference/ch-unit-001-ref.html
new file mode 100644
index 0000000000..163ad8e6c4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ch-unit-001-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test Reference File</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<style>
+svg { width: 10ch; }
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <svg viewBox="0 0 100 100"><rect x="0" y="0" width="100" height="100" fill="green"></svg>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/reference/ch-unit-002-ref.html b/testing/web-platform/tests/css/css-values/reference/ch-unit-002-ref.html
new file mode 100644
index 0000000000..ee6ce1595d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ch-unit-002-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test Reference File</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<style>
+svg {
+ width: 10ch;
+ writing-mode: vertical-rl;
+ text-orientation: upright;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <svg viewBox="0 0 100 100"><rect x="0" y="0" width="100" height="100" fill="green"></svg>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/reference/ch-unit-008-ref.html b/testing/web-platform/tests/css/css-values/reference/ch-unit-008-ref.html
new file mode 100644
index 0000000000..678a9c1695
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ch-unit-008-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test Reference File</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+ <style>
+ div
+ {
+ float: left;
+ font-size: 80px; /* arbitrary font size */
+ line-height: 1.8; /* arbitrary line-height */
+ }
+
+ div#blue
+ {
+ background-color: blue;
+ color: blue;
+ }
+
+ div#orange
+ {
+ background-color: orange;
+ color: orange;
+ clear: left;
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same width</strong> as an orange rectangle.
+
+ <div id="blue">00000</div>
+
+ <div id="orange">00000</div>
diff --git a/testing/web-platform/tests/css/css-values/reference/ch-unit-009-ref.html b/testing/web-platform/tests/css/css-values/reference/ch-unit-009-ref.html
new file mode 100644
index 0000000000..6bd69bed09
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ch-unit-009-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test Reference File</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+ <style>
+ div
+ {
+ float: left;
+ font-size: 80px; /* arbitrary font size */
+ line-height: 1.8; /* arbitrary line-height */
+ writing-mode: vertical-rl;
+ }
+
+ div#blue
+ {
+ background-color: blue;
+ color: blue;
+ }
+
+ div#orange
+ {
+ background-color: orange;
+ color: orange;
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="blue">00000</div>
+
+ <div id="orange">00000</div>
diff --git a/testing/web-platform/tests/css/css-values/reference/ch-unit-011-ref.html b/testing/web-platform/tests/css/css-values/reference/ch-unit-011-ref.html
new file mode 100644
index 0000000000..78b484fe71
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ch-unit-011-ref.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test Reference File</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+ <style>
+ div
+ {
+ float: left;
+ font-size: 80px; /* arbitrary font size */
+ line-height: 1.8; /* arbitrary line-height */
+ text-orientation: upright;
+ writing-mode: vertical-rl;
+ }
+
+ div#blue
+ {
+ background-color: blue;
+ color: blue;
+ }
+
+ div#orange
+ {
+ background-color: orange;
+ color: orange;
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="blue">00000</div>
+
+ <div id="orange">00000</div>
diff --git a/testing/web-platform/tests/css/css-values/reference/ch-unit-016-ref.html b/testing/web-platform/tests/css/css-values/reference/ch-unit-016-ref.html
new file mode 100644
index 0000000000..74e304be72
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ch-unit-016-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test Reference File</title>
+<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
+<style>
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+ width: 100px;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<div></div>
+<div></div>
diff --git a/testing/web-platform/tests/css/css-values/reference/ex-unit-001-ref.html b/testing/web-platform/tests/css/css-values/reference/ex-unit-001-ref.html
new file mode 100644
index 0000000000..33b241f58c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ex-unit-001-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test Reference</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<meta name="flags" content="ahem">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+ @font-face {
+ font-family: foo;
+ font-weight: 900;
+ src: url('/fonts/noto/noto-sans-v8-latin-regular.woff');
+ }
+ div {
+ font-family: foo, sans-serif;
+ font-weight: 900;
+ width: 10ex;
+ height: 20px;
+ background: blue;
+ margin: 20px;
+ font-size: 20px;
+ }
+</style>
+<p>All lines except the first should be the same length</p>
+<div style="font-family: Ahem; font-weight: normal;"></div>
+<div></div>
+<div></div>
+<div></div>
diff --git a/testing/web-platform/tests/css/css-values/reference/ex-unit-002-ref.html b/testing/web-platform/tests/css/css-values/reference/ex-unit-002-ref.html
new file mode 100644
index 0000000000..74e304be72
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ex-unit-002-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test Reference File</title>
+<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
+<style>
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+ width: 100px;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<div></div>
+<div></div>
diff --git a/testing/web-platform/tests/css/css-values/reference/ex-unit-004-ref.html b/testing/web-platform/tests/css/css-values/reference/ex-unit-004-ref.html
new file mode 100644
index 0000000000..938cc3456e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ex-unit-004-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test Reference File</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<style>
+div {
+ height: 10px;
+ background-color: blue;
+ margin-top: 10px;
+ font-size: 80px;
+ width: 10ex;
+ font-family: Arial, sans-serif;
+}
+</style>
+<p>The test passes if there are two blue rectangles of equal length.</p>
+<div></div>
+<div></div>
diff --git a/testing/web-platform/tests/css/css-values/reference/ic-unit-001-ref.html b/testing/web-platform/tests/css/css-values/reference/ic-unit-001-ref.html
new file mode 100644
index 0000000000..24711fefb4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ic-unit-001-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test Reference File</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<style>
+.ref {
+ width: 200px;
+ height: 200px;
+ background: green;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="ref"></div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/reference/ic-unit-002-ref.html b/testing/web-platform/tests/css/css-values/reference/ic-unit-002-ref.html
new file mode 100644
index 0000000000..24711fefb4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ic-unit-002-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values and Units Test Reference File</title>
+<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
+<style>
+.ref {
+ width: 200px;
+ height: 200px;
+ background: green;
+}
+</style>
+<body>
+ <p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
+ <div class="ref"></div>
+</body>
diff --git a/testing/web-platform/tests/css/css-values/reference/ic-unit-008-ref.html b/testing/web-platform/tests/css/css-values/reference/ic-unit-008-ref.html
new file mode 100644
index 0000000000..9db473c4c1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ic-unit-008-ref.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test Reference File</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+ <style>
+ @font-face
+ {
+ font-family: IcTestFullWidth;
+ src: url(/css/css-values/resources/IcTestFullWidth.woff2);
+ }
+
+ div
+ {
+ float: left;
+ font-family: IcTestFullWidth;
+ font-size: 80px; /* arbitrary font size */
+ line-height: 1.8; /* arbitrary line-height */
+ }
+
+ div#blue
+ {
+ background-color: blue;
+ color: blue;
+ }
+
+ div#orange
+ {
+ background-color: orange;
+ color: orange;
+ clear: left;
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same width</strong> as an orange rectangle.
+
+ <div id="blue">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <div id="orange">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <!--
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#27700;
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#x6C34;
+
+ -->
diff --git a/testing/web-platform/tests/css/css-values/reference/ic-unit-009-ref.html b/testing/web-platform/tests/css/css-values/reference/ic-unit-009-ref.html
new file mode 100644
index 0000000000..4330052272
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ic-unit-009-ref.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test Reference File</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+ <style>
+ @font-face
+ {
+ font-family: IcTestFullWidth;
+ src: url(/css/css-values/resources/IcTestFullWidth.woff2);
+ }
+
+ div
+ {
+ float: left;
+ font-family: IcTestFullWidth;
+ font-size: 80px; /* arbitrary font size */
+ line-height: 1.8; /* arbitrary line-height */
+ writing-mode: vertical-rl;
+ }
+
+ div#blue
+ {
+ background-color: blue;
+ color: blue;
+ }
+
+ div#orange
+ {
+ background-color: orange;
+ color: orange;
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="blue">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <div id="orange">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <!--
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#27700;
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#x6C34;
+
+ -->
diff --git a/testing/web-platform/tests/css/css-values/reference/ic-unit-012-ref.html b/testing/web-platform/tests/css/css-values/reference/ic-unit-012-ref.html
new file mode 100644
index 0000000000..43069859c7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ic-unit-012-ref.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test Reference File</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+ <style>
+ @font-face
+ {
+ font-family: IcTestFullWidth;
+ src: url(/css/css-values/resources/IcTestFullWidth.woff2);
+ }
+
+ div
+ {
+ float: left;
+ font-family: IcTestFullWidth;
+ font-size: 80px; /* arbitrary font size */
+ line-height: 1.8; /* arbitrary line-height */
+ text-orientation: sideways;
+ writing-mode: vertical-rl;
+ }
+
+ div#blue
+ {
+ background-color: blue;
+ color: blue;
+ }
+
+ div#orange
+ {
+ background-color: orange;
+ color: orange;
+ }
+ </style>
+
+ <p>Test passes if there is a blue rectangle with the <strong>same height</strong> as an orange rectangle.
+
+ <div id="blue">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <div id="orange">&#27700;&#27700;&#27700;&#27700;&#27700;</div>
+
+ <!--
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#27700;
+
+ 水 (CJK water ideograph, U+6C34) glyph == &#x6C34;
+
+ -->
diff --git a/testing/web-platform/tests/css/css-values/reference/ic-unit-013-ref.html b/testing/web-platform/tests/css/css-values/reference/ic-unit-013-ref.html
new file mode 100644
index 0000000000..67e75b953f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ic-unit-013-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ic unit</title>
+<style>
+.test, .ref {
+ width: 100px;
+ height: 20px;
+ background: green;
+}
+
+.test {
+ margin-bottom: 10px;
+}
+</style>
+
+<p>The test passes if there are two green rectangles of equal length.</p>
+<div class="test"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/reference/ic-unit-014-ref.html b/testing/web-platform/tests/css/css-values/reference/ic-unit-014-ref.html
new file mode 100644
index 0000000000..2e5c9b43b4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/ic-unit-014-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+
+<meta charset="utf-8">
+<title>CSS Values and Units Test: support for the ic unit</title>
+<style>
+.test, .ref {
+ width: 200px;
+ height: 20px;
+ background: green;
+}
+
+.test {
+ margin-bottom: 10px;
+}
+</style>
+
+<p>The test passes if there are two green rectangles of equal length.</p>
+<div class="test"></div>
+<div class="ref"></div>
diff --git a/testing/web-platform/tests/css/css-values/reference/vh-support-atviewport-ref.htm b/testing/web-platform/tests/css/css-values/reference/vh-support-atviewport-ref.htm
new file mode 100644
index 0000000000..cfa9e8d02d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/vh-support-atviewport-ref.htm
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html><head>
+ <meta charset="utf-8">
+ <title>
+ CSS Reftest Reference
+ </title>
+
+ <link href="mailto:fremycompany.developer@yahoo.fr" rel="author" title="François REMY">
+
+ <style type="text/css">
+ html
+ {
+ background-color: yellow;
+ border-left: blue solid 50vw;
+ height: 100vh;
+ }
+ </style>
+
+</head>
+<body>
+
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/reference/vh_not_refreshing_on_chrome-ref.html b/testing/web-platform/tests/css/css-values/reference/vh_not_refreshing_on_chrome-ref.html
new file mode 100644
index 0000000000..279d1c69b9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/vh_not_refreshing_on_chrome-ref.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<!-- Submitted from TestTWF Paris -->
+<head>
+
+ <title>CSS Reference File</title>
+ <link rel="author" title="Marc Bourlon" href="mailto:marc@bourlon.com">
+ <script src="/common/reftest-wait.js"></script>
+
+ <style type="text/css">
+
+ * { margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; font-size: 13px; }
+
+ #frameTest { width: 600px; height: 200px; border: 1px solid #000; }
+
+ </style>
+
+ <script type="text/javascript">
+ 'use strict';
+
+ // We must not capture the screen until the frameTest
+ // and testBoxWithVhOnly elements have finished changing height.
+ var elementsPending = 2;
+ function receiveMessage() {
+ if (--elementsPending === 0) {
+ takeScreenshot();
+ }
+ }
+
+ window.addEventListener('message', receiveMessage, false);
+
+ var height = 200;
+
+ function resizeReference() {
+
+ var frameTest = document.getElementById('frameTest');
+
+ // let's resize the iframe vertically only, showing that the vh sizes is not updated.
+ if (height < 300) {
+
+ //frameTest.style.width = height++ + "px";
+ frameTest.style.height = ++height + "px";
+
+ setTimeout(resizeReference, 10);
+
+ } else {
+
+ // uncomment the next line to see how a width resize triggers a layout recalculation
+ //frameTest.style.width = (parseInt(window.getComputedStyle(document.getElementById('frameTest'))['width'], 10) + 1) + "px";
+
+ window.postMessage('frameTest', '*');
+ }
+
+ }
+
+ setTimeout(resizeReference, 10);
+ </script>
+
+</head>
+<body>
+
+<iframe id="frameTest" src="vh_not_refreshing_on_chrome_iframe-ref.html" frameborder="0"></iframe>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/reference/vh_not_refreshing_on_chrome_iframe-ref.html b/testing/web-platform/tests/css/css-values/reference/vh_not_refreshing_on_chrome_iframe-ref.html
new file mode 100644
index 0000000000..5e35f6261e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/vh_not_refreshing_on_chrome_iframe-ref.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<!-- Submitted from TestTWF Paris -->
+<head>
+
+ <title>CSS Reference File</title>
+ <link rel="author" title="Marc Bourlon" href="mailto:marc@bourlon.com">
+
+ <style type="text/css">
+
+ * { margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; font-size: 13px; }
+
+ #testBoxWithVhOnly { background: #F00; width: 60px; float: left; }
+ #testBoxNotGrownHorizontallyByJS { background: #F0F; height: 60px; float: left; }
+ #testBoxWithTransition { background: #FF0; width: 40px; height: 40px; float: left; }
+ #referenceBoxGrownHorizontallyByJS { background: #0F0; height: 40px; float: left; }
+
+ p { clear: both; margin: 10px 0; }
+
+ </style>
+
+</head>
+<body>
+
+<p>
+ All boxes should end up the same size. The green box is the reference one.
+</p>
+
+<div id="testBoxWithVhOnly"></div>
+<div id="testBoxNotGrownHorizontallyByJS"></div>
+<div id="testBoxWithTransition"></div>
+<div id="referenceBoxGrownHorizontallyByJS"></div>
+
+<script type="text/javascript">
+ 'use strict';
+
+ // In case this file was opened by mistake, redirects to proper test
+ if (window.top.location.href === document.location.href) {
+
+ window.top.location.href = "vh_not_refreshing_on_chrome-ref.html";
+
+ }
+
+ function setDimension(id, dimension, value) {
+
+ var element = document.getElementById(id);
+
+ element.style[dimension] = value + "px";
+
+ }
+
+ function animate() {
+
+ var viewportHeight = document.documentElement.clientHeight;
+
+ var sizeH = 20;
+
+ var referenceDimension = Math.round(sizeH * viewportHeight / 100);
+
+ setDimension('testBoxWithVhOnly', 'height', referenceDimension);
+ setDimension('testBoxNotGrownHorizontallyByJS', 'width', referenceDimension);
+ setDimension('testBoxWithTransition', 'width', referenceDimension);
+ setDimension('testBoxWithTransition', 'height', referenceDimension);
+ setDimension('referenceBoxGrownHorizontallyByJS', 'width', referenceDimension);
+ setDimension('referenceBoxGrownHorizontallyByJS', 'height', referenceDimension);
+
+ if (referenceDimension < 60) {
+ setTimeout(animate, 20);
+ } else {
+ parent.postMessage('testBoxWithVhOnly', '*');
+ }
+ }
+
+ setTimeout(animate, 20);
+
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/reference/viewport-unit-011-ref.html b/testing/web-platform/tests/css/css-values/reference/viewport-unit-011-ref.html
new file mode 100644
index 0000000000..e56c6ec845
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/reference/viewport-unit-011-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test Reference File</title>
+
+<style>
+body {
+ margin: 0;
+ height: 100vh;
+}
+div {
+ width: 60%;
+ height: 60%;
+ background-color: green;
+}
+</style>
+<div>
+</div>
diff --git a/testing/web-platform/tests/css/css-values/rem-root-font-size-restyle-1-ref.html b/testing/web-platform/tests/css/css-values/rem-root-font-size-restyle-1-ref.html
new file mode 100644
index 0000000000..a1a1430d35
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/rem-root-font-size-restyle-1-ref.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<title>CSS Test reference</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+:root {
+ font-size: 2em;
+}
+
+div {
+ width: 10rem;
+ height: 10rem;
+ background: green;
+}
+</style>
+<div></div>
diff --git a/testing/web-platform/tests/css/css-values/rem-root-font-size-restyle-1.html b/testing/web-platform/tests/css/css-values/rem-root-font-size-restyle-1.html
new file mode 100644
index 0000000000..0f236cb3df
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/rem-root-font-size-restyle-1.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>CSS Test: Test for rem units on the root element</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" href="https://drafts.csswg.org/css-values/#rem">
+<link rel="match" href="rem-root-font-size-restyle-1-ref.html">
+<style>
+:root {
+ font-size: 2rem;
+}
+
+div {
+ width: 10rem;
+ height: 10rem;
+ background: green;
+}
+</style>
+<div></div>
+<script>
+ document.documentElement.offsetTop;
+ // Force a style recalc.
+ document.documentElement.style.color = "green";
+</script>
diff --git a/testing/web-platform/tests/css/css-values/rem-unit-root-element.html b/testing/web-platform/tests/css/css-values/rem-unit-root-element.html
new file mode 100644
index 0000000000..cfd7af17c4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/rem-unit-root-element.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>CSS Values and Units Test: rem units on the root element</title>
+<link rel="help" href="https://drafts.csswg.org/css-values/#rem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ :root {
+ font-size: 50px;
+ margin-left: 2rem;
+ padding-top: 2rem;
+ line-height: 2rem;
+ }
+</style>
+<script>
+ let rootStyle = getComputedStyle(document.documentElement);
+ test(() => assert_equals(rootStyle.marginLeft, "100px"), "rem based margin.");
+ test(() => assert_equals(rootStyle.paddingTop, "100px"), "rem based padding.");
+ test(() => assert_equals(rootStyle.lineHeight, "100px"), "rem based line-height.");
+
+ test(() => {
+ document.documentElement.style.fontSize = "initial";
+ let initialFontSize = parseInt(getComputedStyle(document.documentElement).fontSize);
+ document.documentElement.style.fontSize = "3rem";
+ assert_equals(getComputedStyle(document.documentElement).fontSize, 3*initialFontSize + "px");
+ }, "Check that rem font-size is based on the initial font-size.");
+</script>
diff --git a/testing/web-platform/tests/css/css-values/resources/ChTestShortZero.woff b/testing/web-platform/tests/css/css-values/resources/ChTestShortZero.woff
new file mode 100644
index 0000000000..c7e7cc5ad8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/resources/ChTestShortZero.woff
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/resources/ChTestZeroWidthZero.woff b/testing/web-platform/tests/css/css-values/resources/ChTestZeroWidthZero.woff
new file mode 100644
index 0000000000..9c34dda475
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/resources/ChTestZeroWidthZero.woff
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/resources/ExTest-NoSpace.woff b/testing/web-platform/tests/css/css-values/resources/ExTest-NoSpace.woff
new file mode 100644
index 0000000000..31312cb801
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/resources/ExTest-NoSpace.woff
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/resources/ExTest.woff b/testing/web-platform/tests/css/css-values/resources/ExTest.woff
new file mode 100644
index 0000000000..0dbc17cf2a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/resources/ExTest.woff
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/resources/IcTestFullWidth.woff2 b/testing/web-platform/tests/css/css-values/resources/IcTestFullWidth.woff2
new file mode 100644
index 0000000000..a4ebf4fc09
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/resources/IcTestFullWidth.woff2
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/resources/IcTestHalfWidth.woff2 b/testing/web-platform/tests/css/css-values/resources/IcTestHalfWidth.woff2
new file mode 100644
index 0000000000..a545d2c730
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/resources/IcTestHalfWidth.woff2
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/resources/IcTestZeroWidth.woff2 b/testing/web-platform/tests/css/css-values/resources/IcTestZeroWidth.woff2
new file mode 100644
index 0000000000..4c90173a93
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/resources/IcTestZeroWidth.woff2
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/rex-invalidation.html b/testing/web-platform/tests/css/css-values/rex-invalidation.html
new file mode 100644
index 0000000000..439106b54b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/rex-invalidation.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>CSS Values and Units Test: rex invalidation</title>
+<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#font-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="assert" content="test rex invalidation">
+<style>
+ @import url("/fonts/ahem.css");
+ html {
+ font-family: 'Ahem';
+ font-size: 40px;
+ }
+ body {
+ font-family: monospace;
+ font-size: 20px;
+ }
+ div {
+ height: 10rex;
+ width: 10rex;
+ }
+</style>
+
+<html>
+ <body>
+ <div id="div"></div>
+ </body>
+</html>
+
+<script>
+ setup({ single_test: true });
+ let old_width = div.getBoundingClientRect().width;
+ document.documentElement.style.fontFamily = "sans-serif";
+ let new_width = div.getBoundingClientRect().width;
+ assert_not_equals(old_width, new_width, "expect the x-height of Ahem and sans-serif to be different");
+ done();
+</script>
diff --git a/testing/web-platform/tests/css/css-values/rgba-011.html b/testing/web-platform/tests/css/css-values/rgba-011.html
new file mode 100644
index 0000000000..393f2a2990
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/rgba-011.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: rgba() function syntax (complex)</title>
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css-color-3/#rgba-color">
+ <link rel="help" href="https://www.w3.org/TR/css-color-4/#rgb-functions">
+ <link rel="help" href="https://www.w3.org/TR/css-values-4/#combine-integers">
+
+ <meta name="assert" content="This test checks the syntax allowed by rgba() function. White space characters, instead of commas, are allowed between numerical values. <alpha-value> can be omitted for rgba() function, in which case it must defaults to 100%. Finally, rgba() function can take real numbers but their computed values will be rounded to the nearest integer, with values halfway between adjacent integers rounded towards positive infinity.">
+
+ <script src="/resources/testharness.js"></script>
+
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="log"></div>
+
+ <div id="target"></div>
+
+ <script>
+ function startTesting()
+ {
+
+ var targetElement = document.getElementById("target");
+
+ function compareValue(property_name, calcValue, expectedValue, description)
+ {
+
+ test(function()
+ {
+
+ targetElement.style.setProperty(property_name, calcValue);
+
+ var computedCalcValue = getComputedStyle(targetElement)[property_name];
+
+ targetElement.style.setProperty(property_name, expectedValue);
+
+ var computedExpectedValue = getComputedStyle(targetElement)[property_name];
+
+ assert_equals(computedCalcValue, computedExpectedValue);
+
+ }, description);
+ }
+
+ compareValue("background-color", "rgba(0.4 127.5 0.3)", "rgb(0, 128, 0)", "testing background-color: rgba(0.4 127.5 0.3)");
+
+ }
+
+ startTesting();
+
+ </script>
diff --git a/testing/web-platform/tests/css/css-values/ric-invalidation.html b/testing/web-platform/tests/css/css-values/ric-invalidation.html
new file mode 100644
index 0000000000..60abb8b5eb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/ric-invalidation.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>CSS Values and Units Test: ric invalidation</title>
+<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#font-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="assert" content="test ric invalidation">
+<style>
+ @import url("/fonts/ahem.css");
+ html {
+ font-family: 'Ahem';
+ font-size: 40px;
+ }
+ body {
+ font-family: monospace;
+ font-size: 20px;
+ }
+ div {
+ width: 10ric;
+ }
+</style>
+
+<html>
+ <body>
+ <div id="div"></div>
+ </body>
+</html>
+
+<script>
+ setup({ single_test: true });
+ let old_width = div.getBoundingClientRect().width;
+ document.documentElement.style.fontSize = "41px";
+ let new_width = div.getBoundingClientRect().width;
+ assert_not_equals(old_width, new_width, "expect update of ric units with font size change");
+ done();
+</script>
diff --git a/testing/web-platform/tests/css/css-values/rlh-invalidation.html b/testing/web-platform/tests/css/css-values/rlh-invalidation.html
new file mode 100644
index 0000000000..4618d9e51a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/rlh-invalidation.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<title>CSS Values and Units Test: rlh invalidation</title>
+<link rel="author" title="Daniil Sakhapov" href="sakhapov@google.com">
+<link rel="help" href="https://drafts.csswg.org/css-values/#font-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="assert" content="test rlh invalidation">
+<style>
+ @import url("/fonts/ahem.css");
+ html {
+ font-family: 'Ahem';
+ font-size: 40px;
+ line-height: 2;
+ }
+ body {
+ font-family: monospace;
+ font-size: 20px;
+ line-height: 5;
+ }
+ div {
+ width: 10rlh;
+ }
+</style>
+
+<html>
+ <body>
+ <div id="div"></div>
+ </body>
+</html>
+
+<script>
+ setup({ single_test: true });
+ let old_width = div.getBoundingClientRect().width;
+ document.documentElement.style.lineHeight = "4";
+ let new_width = div.getBoundingClientRect().width;
+ assert_not_equals(old_width, new_width, "expect rlh units to update on line-height update");
+ old_width = new_width;
+ document.documentElement.style.fontSize = "41px";
+ new_width = div.getBoundingClientRect().width;
+ assert_not_equals(old_width, new_width, "expect rlh units to update on font-size update");
+ done();
+</script>
diff --git a/testing/web-platform/tests/css/css-values/round-function.html b/testing/web-platform/tests/css/css-values/round-function.html
new file mode 100644
index 0000000000..bc8734b011
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/round-function.html
@@ -0,0 +1,97 @@
+<!doctype html>
+<title>round() function</title>
+<meta charset=utf-8>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+
+<meta name=author content="Tab Atkins-Bittner">
+<link rel=help href="https://drafts.csswg.org/css-values-4/#round-func">
+
+<div id=target></div>
+<script>
+// No-op round should be same as nearest
+test_math_used("round(23px, 10px)", "20px");
+test_math_used("round(18px, 10px)", "20px");
+test_math_used("round(15px, 10px)", "20px");
+test_math_used("round(13px, 10px)", "10px");
+test_math_used("round(-13px, 10px)", "-10px");
+test_math_used("round(-18px, 10px)", "-20px");
+
+// Test nearest
+test_math_used("round(nearest, 23px, 10px)", "20px");
+test_math_used("round(nearest, 18px, 10px)", "20px");
+test_math_used("round(nearest, 15px, 10px)", "20px");
+test_math_used("round(nearest, 13px, 10px)", "10px");
+test_math_used("round(nearest, -13px, 10px)", "-10px");
+test_math_used("round(nearest, -18px, 10px)", "-20px");
+
+// Test down
+test_math_used("round(down, 23px, 10px)", "20px");
+test_math_used("round(down, 18px, 10px)", "10px");
+test_math_used("round(down, 15px, 10px)", "10px");
+test_math_used("round(down, 13px, 10px)", "10px");
+test_math_used("round(down, -13px, 10px)", "-20px");
+test_math_used("round(down, -18px, 10px)", "-20px");
+
+// Test up
+test_math_used("round(up, 23px, 10px)", "30px");
+test_math_used("round(up, 18px, 10px)", "20px");
+test_math_used("round(up, 15px, 10px)", "20px");
+test_math_used("round(up, 13px, 10px)", "20px");
+test_math_used("round(up, -13px, 10px)", "-10px");
+test_math_used("round(up, -18px, 10px)", "-10px");
+
+// Test to-zero
+test_math_used("round(to-zero, 23px, 10px)", "20px");
+test_math_used("round(to-zero, 18px, 10px)", "10px");
+test_math_used("round(to-zero, 15px, 10px)", "10px");
+test_math_used("round(to-zero, 13px, 10px)", "10px");
+test_math_used("round(to-zero, -13px, 10px)", "-10px");
+test_math_used("round(to-zero, -18px, 10px)", "-10px");
+
+// Test a negative step
+test_math_used("round(23px, -10px)", "20px");
+test_math_used("round(18px, -10px)", "20px");
+test_math_used("round(15px, -10px)", "20px");
+test_math_used("round(13px, -10px)", "10px");
+test_math_used("round(-13px, -10px)", "-10px");
+test_math_used("round(-18px, -10px)", "-20px");
+
+// Extreme cases:
+
+// 0 step is NaN
+test_nan("round(5, 0)");
+// both infinite is NaN
+test_nan("round(infinity, infinity)");
+test_nan("round(infinity, -infinity)");
+test_nan("round(-infinity, infinity)");
+test_nan("round(-infinity, -infinity)");
+
+// infinite value with finite step is the same infinity
+test_plus_infinity("round(infinity, 5)");
+test_plus_infinity("round(infinity, -5)");
+test_minus_infinity("round(-infinity, 5)");
+test_minus_infinity("round(-infinity, -5)");
+
+// Finite value with infinite step depends on rounding strategy.
+// 'nearest' and 'to-zero': pos and +0 go to +0, neg and -0 go to -0
+test_plus_zero("round(5, infinity)");
+test_plus_zero("round(5, -infinity)");
+test_minus_zero("round(-5, infinity)");
+test_minus_zero("round(-5, -infinity)");
+test_plus_zero("round(to-zero, 5, infinity)");
+test_plus_zero("round(to-zero, 5, -infinity)");
+test_minus_zero("round(to-zero, -5, infinity)");
+test_minus_zero("round(to-zero, -5, -infinity)");
+// 'up': pos goes to +inf, 0+ goes to 0+, else 0-
+test_plus_infinity("round(up, 1, infinity)");
+test_plus_zero("round(up, 0, infinity)");
+test_minus_zero("round(up, -1 * 0, infinity)");
+test_minus_zero("round(up, -1, infinity)");
+// 'down': neg goes to -inf, -0 goes to -0, else 0+
+test_minus_infinity("round(down, -1, infinity)");
+test_minus_zero("round(down, -1 * 0, infinity)");
+test_plus_zero("round(down, 0, infinity)");
+test_plus_zero("round(down, 1, infinity)");
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/round-mod-rem-computed.html b/testing/web-platform/tests/css/css-values/round-mod-rem-computed.html
new file mode 100644
index 0000000000..4c365eb2a1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/round-mod-rem-computed.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div style="width: 75px;">
+ <div id="target"></div>
+</div>
+<script>
+// Simple tests
+test_math_used('round(10,10)', '10', {type:'number'});
+test_math_used('mod(1,1)', '0', {type:'number'});
+test_math_used('rem(1,1)', '0', {type:'number'});
+
+//Test basic round
+test_math_used('calc(round(100,10))', '100', {type:'number'});
+test_math_used('calc(round(up, 101,10))', '110', {type:'number'});
+test_math_used('calc(round(down, 106,10))', '100', {type:'number'});
+test_math_used('calc(round(to-zero,105, 10))', '100', {type:'number'});
+test_math_used('calc(round(to-zero,-105, 10))', '-100', {type:'number'});
+test_math_used('calc(round(-100,10))', '-100', {type:'number'});
+test_math_used('calc(round(up, -103,10))', '-100', {type:'number'});
+
+//Test basic mod/rem
+test_math_used('mod(18,5)', '3', {type:'number'});
+test_math_used('rem(18,5)', '3', {type:'number'});
+test_math_used('mod(-140,-90)', '-50', {type:'number'});
+test_math_used('mod(-18,5)', '2', {type:'number'});
+test_math_used('rem(-18,5)', '-3', {type:'number'});
+test_math_used('mod(140,-90)', '-40', {type:'number'});
+test_math_used('rem(140,-90)', '50', {type:'number'});
+
+//Test basic calculations
+test_math_used('calc(round(round(100,10), 10))', '100', {type:'number'});
+test_math_used('calc(round(up, round(100,10) + 1,10))', '110', {type:'number'});
+test_math_used('calc(round(down, round(100,10) + 2 * 3,10))', '100', {type:'number'});
+test_math_used('calc(round(to-zero,round(100,10) * 2 - 95, 10))', '100', {type:'number'});
+test_math_used('calc(round(round(100,10)* -1,10))', '-100', {type:'number'});
+test_math_used('calc(round(up, -103 + -103 / -103 - 1,10))', '-100', {type:'number'});
+test_math_used('calc(mod(18,5) * 2 + mod(17,5))', '8', {type:'number'});
+test_math_used('calc(rem(mod(18,5),5))', '3', {type:'number'});
+test_math_used('calc(rem(mod(18,5),mod(17,5)))', '1', {type:'number'});
+test_math_used('calc(mod(-140,-90))', '-50', {type:'number'});
+test_math_used('calc(mod(rem(1,18)* -1,5))', '4', {type:'number'});
+
+// Type check
+test_math_used('round(10px,6px)', '12px');
+test_math_used('round(10cm,6cm)', '12cm');
+test_math_used('round(10mm,6mm)', '12mm');
+test_math_used('round(10Q, 6Q)', '12Q');
+test_math_used('round(10in,6in)', '12in');
+test_math_used('round(10pc,6pc)', '12pc');
+test_math_used('round(10pt,6pt)', '12pt');
+test_math_used('round(10em,6em)', '12em');
+test_math_used('round(10ex,6ex)', '12ex');
+test_math_used('round(10ch,6ch)', '12ch');
+test_math_used('round(10rem,6rem)', '12rem');
+test_math_used('round(10vh,6vh)', '12vh');
+test_math_used('round(10vw,6vw)', '12vw');
+test_math_used('round(10vmin,6vmin)', '12vmin');
+test_math_used('round(10vmax,6vmax)', '12vmax');
+test_math_used('round(10s,6s)', '12s', {type:'time'});
+test_math_used('round(10ms,6ms)', '12ms', {type:'time'});
+test_math_used('round(10deg,6deg)', '12deg', {type:'angle', approx:0.1});
+test_math_used('round(10grad,6grad)', '12grad', {type:'angle', approx:0.1});
+test_math_used('round(10rad,6rad)', '12rad',{type:'angle', approx:0.1});
+test_math_used('round(10turn,6turn)', '12turn',{type:'angle', approx:0.1});
+
+test_math_used('mod(10px,6px)', '4px');
+test_math_used('mod(10cm,6cm)', '4cm');
+test_math_used('mod(10mm,6mm)', '4mm');
+test_math_used('mod(10Q, 6Q)', '4Q');
+test_math_used('mod(10in,6in)', '4in');
+test_math_used('mod(10pc,6pc)', '4pc');
+test_math_used('mod(10em,6em)', '4em');
+test_math_used('mod(10ex,6ex)', '4ex');
+test_math_used('mod(10ch,6ch)', '4ch');
+test_math_used('mod(10rem,6rem)', '4rem');
+test_math_used('mod(10vh,6vh)', '4vh');
+test_math_used('mod(10vw,6vw)', '4vw');
+test_math_used('mod(10vmin,6vmin)', '4vmin');
+test_math_used('mod(10vmax,6vmax)', '4vmax');
+test_math_used('mod(10s,6s)', '4s', {type:'time'});
+test_math_used('mod(10ms,6ms)', '4ms', {type:'time'});
+test_math_used('mod(10deg,6deg)', '4deg', {type:'angle', approx:0.1});
+test_math_used('mod(10grad,6grad)', '4grad', {type:'angle', approx:0.1});
+test_math_used('mod(10rad,6rad)', '4rad',{type:'angle', approx:0.1});
+test_math_used('mod(10turn,6turn)', '4turn',{type:'angle', approx:0.1});
+
+test_math_used('rem(10px,6px)', '4px');
+test_math_used('rem(10cm,6cm)', '4cm');
+test_math_used('rem(10mm,6mm)', '4mm');
+test_math_used('rem(10Q, 6Q)', '4Q');
+test_math_used('rem(10in,6in)', '4in');
+test_math_used('rem(10pc,6pc)', '4pc');
+test_math_used('rem(10em,6em)', '4em');
+test_math_used('rem(10ex,6ex)', '4ex');
+test_math_used('rem(10ch,6ch)', '4ch');
+test_math_used('rem(10rem,6rem)', '4rem');
+test_math_used('rem(10vh,6vh)', '4vh');
+test_math_used('rem(10vw,6vw)', '4vw');
+test_math_used('rem(10vmin,6vmin)', '4vmin');
+test_math_used('rem(10vmax,6vmax)', '4vmax');
+test_math_used('rem(10s,6s)', '4s', {type:'time'});
+test_math_used('rem(10ms,6ms)', '4ms', {type:'time'});
+test_math_used('rem(10deg,6deg)', '4deg', {type:'angle', approx:0.1});
+test_math_used('rem(10grad,6grad)', '4grad', {type:'angle', approx:0.1});
+test_math_used('rem(10rad,6rad)', '4rad',{type:'angle', approx:0.1});
+test_math_used('rem(10turn,6turn)', '4turn',{type:'angle', approx:0.1});
+
+//Test percentage and mixed units
+test_math_used('round(10%,1px)', '8px');
+test_math_used('round(10%,5px)', '10px');
+test_math_used('round(2rem,5px)', '30px');
+test_math_used('round(100px,1rem)', '96px');
+test_math_used('round(10s,6000ms)', '12s', {type:'time'});
+test_math_used('round(10000ms,6s)', '12s', {type:'time'});
+
+test_math_used('mod(10%,1px)', '0.5px');
+test_math_used('mod(10%,5px)', '2.5px');
+test_math_used('mod(2rem,5px)', '2px');
+test_math_used('mod(100px,1rem)', '4px');
+test_math_used('mod(10s,6000ms)', '4s', {type:'time'});
+test_math_used('mod(10000ms,6s)', '4s', {type:'time'});
+test_math_used('mod(18px,100% / 15)', '3px');
+test_math_used('mod(-18px,100% / 15)', '2px');
+test_math_used('mod(18%,5%)', '3%');
+test_math_used('mod(-18%,5%)', '2%');
+test_math_used('mod(18vw,5vw)', '3vw');
+test_math_used('mod(-18vw,5vw)', '2vw');
+
+test_math_used('rem(10%,1px)', '0.5px');
+test_math_used('rem(10%,5px)', '2.5px');
+test_math_used('rem(2rem,5px)', '2px');
+test_math_used('rem(100px,1rem)', '4px');
+test_math_used('rem(10s,6000ms)', '4s', {type:'time'});
+test_math_used('rem(10000ms,6s)', '4s', {type:'time'});
+test_math_used('rem(18px,100% / 15)', '3px');
+test_math_used('rem(-18px,100% / 15)', '-3px');
+test_math_used('rem(18vw,5vw)', '3vw');
+test_math_used('rem(-18vw,5vw)', '-3vw');
+
+test_math_used('calc(round(1px + 0%, 1px + 0%))', '1px');
+test_math_used('calc(mod(1px + 0%, 1px + 0%))', '0px');
+test_math_used('calc(rem(1px + 0%, 1px + 0%))', '0px');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/round-mod-rem-invalid.html b/testing/web-platform/tests/css/css-values/round-mod-rem-invalid.html
new file mode 100644
index 0000000000..99ef2c64b4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/round-mod-rem-invalid.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_number(value) {
+ test_invalid_value('opacity', value);
+}
+
+// Syntax checking
+test_invalid_number('round()');
+test_invalid_number('round( )');
+test_invalid_number('round(,)');
+test_invalid_number('round(1, )');
+test_invalid_number('round(, 1)');
+test_invalid_number('round(1 + )');
+test_invalid_number('round(1 - )');
+test_invalid_number('round(1 * )');
+test_invalid_number('round(1 / )');
+test_invalid_number('round(1 2)');
+test_invalid_number('round(nearest, 1 2)');
+test_invalid_number('round(1, nearest, 12)');
+test_invalid_number('round(1, nearest)');
+test_invalid_number('round(nearest, 1, nearest)');
+test_invalid_number('round(nearest, 1)');
+test_invalid_number('round(1, , 2)');
+test_invalid_number('mod()');
+test_invalid_number('mod( )');
+test_invalid_number('mod(,)');
+test_invalid_number('mod(1, )');
+test_invalid_number('mod(, 1)');
+test_invalid_number('mod(1 + )');
+test_invalid_number('mod(1 - )');
+test_invalid_number('mod(1 * )');
+test_invalid_number('mod(1 / )');
+test_invalid_number('mod(1 2)');
+test_invalid_number('mod(1, , 2)');
+test_invalid_number('rem()');
+test_invalid_number('rem( )');
+test_invalid_number('rem(,)');
+test_invalid_number('rem(1, )');
+test_invalid_number('rem(, 1)');
+test_invalid_number('rem(1 + )');
+test_invalid_number('rem(1 - )');
+test_invalid_number('rem(1 * )');
+test_invalid_number('rem(1 / )');
+test_invalid_number('rem(1 2)');
+test_invalid_number('rem(1, , 2)');
+
+// Type checking
+test_invalid_number('round(0px)');
+test_invalid_number('round(0s)');
+test_invalid_number('round(0deg)');
+test_invalid_number('round(0Hz)');
+test_invalid_number('round(0dpi)');
+test_invalid_number('round(0fr)');
+test_invalid_number('round(1, 1%)');
+test_invalid_number('round(1, 0px)');
+test_invalid_number('round(1, 0s)');
+test_invalid_number('round(1, 0deg)');
+test_invalid_number('round(1, 0Hz)');
+test_invalid_number('round(1, 0dpi)');
+test_invalid_number('round(1, 0fr)');
+test_invalid_number('mod(0px)');
+test_invalid_number('mod(0s)');
+test_invalid_number('mod(0deg)');
+test_invalid_number('mod(0Hz)');
+test_invalid_number('mod(0dpi)');
+test_invalid_number('mod(0fr)');
+test_invalid_number('mod(1, 1%)');
+test_invalid_number('mod(1, 0px)');
+test_invalid_number('mod(1, 0s)');
+test_invalid_number('mod(1, 0deg)');
+test_invalid_number('mod(1, 0Hz)');
+test_invalid_number('mod(1, 0dpi)');
+test_invalid_number('mod(1, 0fr)');
+test_invalid_number('rem(0px)');
+test_invalid_number('rem(0s)');
+test_invalid_number('rem(0deg)');
+test_invalid_number('rem(0Hz)');
+test_invalid_number('rem(0dpi)');
+test_invalid_number('rem(0fr)');
+test_invalid_number('rem(1, 1%)');
+test_invalid_number('rem(1, 0px)');
+test_invalid_number('rem(1, 0s)');
+test_invalid_number('rem(1, 0deg)');
+test_invalid_number('rem(1, 0Hz)');
+test_invalid_number('rem(1, 0dpi)');
+test_invalid_number('rem(1, 0fr)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/round-mod-rem-serialize.html b/testing/web-platform/tests/css/css-values/round-mod-rem-serialize.html
new file mode 100644
index 0000000000..39569995b3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/round-mod-rem-serialize.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(t,s,c) {
+ test_specified_serialization('opacity', t, s);
+ test_specified_serialization('transform', `scale(${t})`, `scale(calc(${c}))`);
+ test_computed_serialization('opacity', t, c);
+ test_computed_serialization('transform', `scale(${t})`, `matrix(${c}, 0, 0, ${c}, 0, 0)`);
+}
+
+test_serialization(
+ 'round(1.1,1)',
+ 'calc(1)',
+ '1');
+test_serialization(
+ 'mod(1,1)',
+ 'calc(0)',
+ '0');
+test_serialization(
+ 'rem(1,1)',
+ 'calc(0)',
+ '0');
+
+test_serialization(
+ 'calc(round(1,0))',
+ 'calc(NaN)',
+ 'NaN');
+test_serialization(
+ 'calc(mod(1,0))',
+ 'calc(NaN)',
+ 'NaN');
+test_serialization(
+ 'calc(rem(1,0))',
+ 'calc(NaN)',
+ 'NaN');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/signs-abs-computed.html b/testing/web-platform/tests/css/css-values/signs-abs-computed.html
new file mode 100644
index 0000000000..774ca34cb7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/signs-abs-computed.html
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="container" style="font-size: 20px">
+ <div id="target"></div>
+</div>
+<script>
+function test_zero(expression, { is_negative }) {
+ test_math_used(`calc(${expression})`, '0', {type:'integer'});
+ // to test zero sign, make it to negative infinity and clamp it between -1 and 1
+ test_math_used(`clamp(-1, calc( 1 / sign(${expression})), 1)`, (is_negative)? '-1' : '1', {type:'integer'});
+}
+
+function test_length_equals(value, expected, msgExtra) {
+ test_math_used(value, expected, {msgExtra, type: 'integer'});
+}
+
+// Identity tests
+test_math_used('abs(1)', '1', {type:'integer'});
+test_math_used('sign(1)', '1', {type:'integer'});
+test_math_used('abs(-1)', '1', {type:'integer'});
+test_math_used('sign(-1)', '-1', {type:'integer'});
+
+// Nestings
+test_math_used('abs(sign(1))', '1', {type:'integer'});
+test_math_used('abs(sign(sign(1)))', '1', {type:'integer'});
+test_math_used('sign(sign(sign(1) + sign(1)))', '1', {type:'integer'});
+
+// General calculations
+test_math_used('calc(abs(0.1 + 0.2) + 0.05)', '0.35', {type:'number', approx:0.1});
+test_math_used('calc(sign(0.1 + 0.2) - 0.05)', '0.95', {type:'number', approx:0.1});
+test_math_used('calc(abs(0.1 + 0.2) * 2)', '0.6', {type:'number', approx:0.1});
+test_math_used('calc(abs(sign(0.1) + 0.2) / 2)', '0.6', {type:'number', approx:0.1});
+test_math_used('calc(abs(0.1 + 0.2) * -2)', '-0.6', {type:'number', approx:0.1});
+test_math_used('calc(sign(0.1 - 0.2) - 0.05)', '-1.05', {type:'number', approx:0.1});
+test_math_used('calc(sign(1) + sign(1) - 0.05)', '1.95', {type:'number', approx:0.1});
+
+// Test sign for zero
+test_zero('calc(sign(-0))', {is_negative: true});
+test_zero('calc(sign(0))', {is_negative: false});
+
+//Type checking sign
+test_math_used('sign(1px)', '1', {type:'integer'});
+test_math_used('sign(1cm)', '1', {type:'integer'});
+test_math_used('sign(1mm)', '1', {type:'integer'});
+test_math_used('sign(1Q)', '1', {type:'integer'});
+test_math_used('sign(1in)', '1', {type:'integer'});
+test_math_used('sign(1pc)', '1', {type:'integer'});
+test_math_used('sign(1pt)', '1', {type:'integer'});
+test_math_used('sign(1em)', '1', {type:'integer'});
+test_math_used('sign(1ex)', '1', {type:'integer'});
+test_math_used('sign(1ch)', '1', {type:'integer'});
+test_math_used('sign(1rem)', '1', {type:'integer'});
+test_math_used('sign(1vh)', '1', {type:'integer'});
+test_math_used('sign(1vw)', '1', {type:'integer'});
+test_math_used('sign(1vmin)', '1', {type:'integer'});
+test_math_used('sign(1vmax)', '1', {type:'integer'});
+test_math_used('sign(-1px)', '-1', {type:'integer'});
+test_math_used('sign(-1cm)', '-1', {type:'integer'});
+test_math_used('sign(-1mm)', '-1', {type:'integer'});
+test_math_used('sign(-1Q)', '-1', {type:'integer'});
+test_math_used('sign(-1in)', '-1', {type:'integer'});
+test_math_used('sign(-1pc)', '-1', {type:'integer'});
+test_math_used('sign(-1pt)', '-1', {type:'integer'});
+test_math_used('sign(-1em)', '-1', {type:'integer'});
+test_math_used('sign(-1ex)', '-1', {type:'integer'});
+test_math_used('sign(-1ch)', '-1', {type:'integer'});
+test_math_used('sign(-1rem)', '-1', {type:'integer'});
+test_math_used('sign(-1vh)', '-1', {type:'integer'});
+test_math_used('sign(-1vw)', '-1', {type:'integer'});
+test_math_used('sign(-1vmin)', '-1', {type:'integer'});
+test_math_used('sign(-1vmax)', '-1', {type:'integer'});
+test_math_used('sign(1s)', '1', {type:'integer'});
+test_math_used('sign(1ms)', '1', {type:'integer'});
+test_math_used('sign(-1s)', '-1', {type:'integer'});
+test_math_used('sign(-1ms)', '-1', {type:'integer'});
+test_math_used('sign(1deg)', '1', {type:'integer'});
+test_math_used('sign(1grad)', '1', {type:'integer'});
+test_math_used('sign(1rad)', '1', {type:'integer'});
+test_math_used('sign(1turn)', '1', {type:'integer'});
+test_math_used('sign(-1deg)', '-1', {type:'integer'});
+test_math_used('sign(-1grad)', '-1', {type:'integer'});
+test_math_used('sign(-1rad)', '-1', {type:'integer'});
+test_math_used('sign(-1turn)', '-1', {type:'integer'});
+test_zero('sign(0px)', {is_negative: false});
+test_zero('sign(0cm)', {is_negative: false});
+test_zero('sign(0mm)', {is_negative: false});
+test_zero('sign(0Q)', {is_negative: false});
+test_zero('sign(0in)', {is_negative: false});
+test_zero('sign(0pc)', {is_negative: false});
+test_zero('sign(0pt)', {is_negative: false});
+test_zero('sign(0em)', {is_negative: false});
+test_zero('sign(0ex)', {is_negative: false});
+test_zero('sign(0ch)', {is_negative: false});
+test_zero('sign(0rem)', {is_negative: false});
+test_zero('sign(0vh)', {is_negative: false});
+test_zero('sign(0vw)', {is_negative: false});
+test_zero('sign(0vmin)', {is_negative: false});
+test_zero('sign(0vmax)', {is_negative: false});
+test_zero('sign(-0px)', {is_negative: true});
+test_zero('sign(-0cm)', {is_negative: true});
+test_zero('sign(-0mm)', {is_negative: true});
+test_zero('sign(-0Q)', {is_negative: true});
+test_zero('sign(-0in)', {is_negative: true});
+test_zero('sign(-0pc)', {is_negative: true});
+test_zero('sign(-0pt)', {is_negative: true});
+test_zero('sign(-0em)', {is_negative: true});
+test_zero('sign(-0ex)', {is_negative: true});
+test_zero('sign(-0ch)', {is_negative: true});
+test_zero('sign(-0rem)', {is_negative: true});
+test_zero('sign(-0vh)', {is_negative: true});
+test_zero('sign(-0vw)', {is_negative: true});
+test_zero('sign(-0vmin)', {is_negative: true});
+test_zero('sign(-0vmax)', {is_negative: true});
+test_zero('sign(0s)', {is_negative: false});
+test_zero('sign(0ms)', {is_negative: false});
+test_zero('sign(-0s)', {is_negative: true});
+test_zero('sign(-0ms)', {is_negative: true});
+test_zero('sign(0deg)', {is_negative: false});
+test_zero('sign(0grad)', {is_negative: false});
+test_zero('sign(0rad)', {is_negative: false});
+test_zero('sign(0turn)', {is_negative: false});
+test_zero('sign(-0deg)', {is_negative: true});
+test_zero('sign(-0grad)', {is_negative: true});
+test_zero('sign(-0rad)', {is_negative: true});
+test_zero('sign(-0turn)', {is_negative: true});
+
+//Type checking abs
+test_math_used('abs(1px)', '1px');
+test_math_used('abs(1cm)', '1cm');
+test_math_used('abs(1mm)', '1mm');
+test_math_used('abs(1Q)', '1Q');
+test_math_used('abs(1in)', '1in');
+test_math_used('abs(1pc)', '1pc');
+test_math_used('abs(1pt)', '1pt');
+test_math_used('abs(1em)', '1em');
+test_math_used('abs(1ex)', '1ex');
+test_math_used('abs(1ch)', '1ch');
+test_math_used('abs(1rem)', '1rem');
+test_math_used('abs(1vh)', '1vh');
+test_math_used('abs(1vw)', '1vw');
+test_math_used('abs(1vmin)', '1vmin');
+test_math_used('abs(1vmax)', '1vmax');
+test_math_used('abs(-1px)', '1px');
+test_math_used('abs(-1cm)', '1cm');
+test_math_used('abs(-1mm)', '1mm');
+test_math_used('abs(-1Q)', '1Q');
+test_math_used('abs(-1in)', '1in');
+test_math_used('abs(-1pc)', '1pc');
+test_math_used('abs(-1pt)', '1pt');
+test_math_used('abs(-1em)', '1em');
+test_math_used('abs(-1ex)', '1ex');
+test_math_used('abs(-1ch)', '1ch');
+test_math_used('abs(-1rem)', '1rem');
+test_math_used('abs(-1vh)', '1vh');
+test_math_used('abs(-1vw)', '1vw');
+test_math_used('abs(-1vmin)', '1vmin');
+test_math_used('abs(-1vmax)', '1vmax');
+test_math_used('abs(1s)', '1s', {type:'time'});
+test_math_used('abs(1ms)', '1ms', {type:'time'});
+test_math_used('abs(-1s)', '1s', {type:'time'});
+test_math_used('abs(-1ms)', '1ms', {type:'time'});
+test_math_used('abs(1deg)', '1deg', {type:'angle', approx:0.001});
+test_math_used('abs(1grad)', '1grad', {type:'angle', approx:0.001});
+test_math_used('abs(1rad)', '1rad', {type:'angle', approx:0.001});
+test_math_used('abs(1turn)', '1turn', {type:'angle', approx:0.001});
+test_math_used('abs(-1deg)', '1deg', {type:'angle', approx:0.001});
+test_math_used('abs(-1grad)', '1grad', {type:'angle', approx:0.001});
+test_math_used('abs(-1rad)', '1rad', {type:'angle', approx:0.001});
+test_math_used('abs(-1turn)', '1turn', {type:'angle', approx:0.001});
+
+// with relative length
+document.getElementById('container').style.fontSize = '10px';
+test_length_equals('sign(10px - 1em)', '0', 'fontSize=10px');
+test_length_equals('sign(10px - 2em)', '-1', 'fontSize=10px');
+document.getElementById('container').style.fontSize = '20px';
+
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/signs-abs-invalid.html b/testing/web-platform/tests/css/css-values/signs-abs-invalid.html
new file mode 100644
index 0000000000..15b058d0c4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/signs-abs-invalid.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_number(value) {
+ test_invalid_value('opacity', value);
+}
+
+// Syntax checking
+test_invalid_number('abs()');
+test_invalid_number('abs( )');
+test_invalid_number('abs(,)');
+test_invalid_number('abs(1, )');
+test_invalid_number('abs(, 1)');
+test_invalid_number('abs(1 + )');
+test_invalid_number('abs(1 - )');
+test_invalid_number('abs(1 * )');
+test_invalid_number('abs(1 / )');
+test_invalid_number('abs(1 2)');
+test_invalid_number('abs(1, , 2)');
+test_invalid_number('abs(1, 2)');
+test_invalid_number('sign()');
+test_invalid_number('sign( )');
+test_invalid_number('sign(,)');
+test_invalid_number('sign(1, )');
+test_invalid_number('sign(, 1)');
+test_invalid_number('sign(1 + )');
+test_invalid_number('sign(1 - )');
+test_invalid_number('sign(1 * )');
+test_invalid_number('sign(1 / )');
+test_invalid_number('sign(1 2)');
+test_invalid_number('sign(1, , 2)');
+test_invalid_number('sign(1, 2)');
+
+// Type checking
+test_invalid_number('abs(0px)');
+test_invalid_number('abs(0s)');
+test_invalid_number('abs(0deg)');
+test_invalid_number('abs(0Hz)');
+test_invalid_number('abs(0dpi)');
+test_invalid_number('abs(0fr)');
+test_invalid_number('abs(1, 1%)');
+test_invalid_number('abs(1, 0px)');
+test_invalid_number('abs(1, 0s)');
+test_invalid_number('abs(1, 0deg)');
+test_invalid_number('abs(1, 0Hz)');
+test_invalid_number('abs(1, 0dpi)');
+test_invalid_number('abs(1, 0fr)');
+test_invalid_number('sign(1, 1%)');
+test_invalid_number('sign(1, 0px)');
+test_invalid_number('sign(1, 0s)');
+test_invalid_number('sign(1, 0deg)');
+test_invalid_number('sign(1, 0Hz)');
+test_invalid_number('sign(1, 0dpi)');
+test_invalid_number('sign(1, 0fr)');
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/signs-abs-serialize.html b/testing/web-platform/tests/css/css-values/signs-abs-serialize.html
new file mode 100644
index 0000000000..ea3d0cb433
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/signs-abs-serialize.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(t,s,c) {
+ test_specified_serialization('transform', `scale(${t})`, `scale(calc(${c}))`);
+}
+
+test_serialization(
+ 'abs(1)',
+ 'calc(1)',
+ '1');
+test_serialization(
+ 'sign(.1)',
+ 'calc(1)',
+ '1');
+
+test_serialization(
+ 'abs(1 + 2 + 3)',
+ 'calc(6)',
+ '6');
+test_serialization(
+ 'sign(1 + 2 + 3)',
+ 'calc(1)',
+ '1');
+
+test_serialization(
+ 'calc(abs(1) + abs(2))',
+ 'calc(3)',
+ '3');
+test_serialization(
+ 'calc(sign(.1) + sign(.2))',
+ 'calc(2)',
+ '2');
+
+test_serialization(
+ 'calc(1 + abs(1))',
+ 'calc(2)',
+ '2');
+test_serialization(
+ 'calc(sign(.1) + 1)',
+ 'calc(2)',
+ '2');
+
+test_serialization(
+ 'calc(abs(inFinity))',
+ 'calc(inFinity)',
+ 'infinity');
+
+test_serialization(
+ 'calc(abs(infinity))',
+ 'calc(infinity)',
+ 'infinity');
+test_serialization(
+ 'calc(sign(infinity))',
+ 'calc(1)',
+ '1');
+test_serialization(
+ 'abs(infinity)',
+ 'calc(infinity)',
+ 'infinity');
+
+test_serialization(
+ 'calc(abs(-infinity))',
+ 'calc(infinity)',
+ 'infinity');
+test_serialization(
+ 'calc(sign(-1 * infinity))',
+ 'calc(-1)',
+ '-1');
+
+test_serialization(
+ 'calc(sign(-1 * NaN))',
+ 'calc(NaN)',
+ 'NaN');
+
+test_serialization(
+ 'calc(sign(1 * NaN))',
+ 'calc(NaN)',
+ 'NaN');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/sin-cos-tan-computed.html b/testing/web-platform/tests/css/css-values/sin-cos-tan-computed.html
new file mode 100644
index 0000000000..bad6017520
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/sin-cos-tan-computed.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<link rel="author" title="Seokho Song" href="seokho@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<script>
+// Simple tests
+test_math_used('cos(0)', '1', {type:'number'});
+test_math_used('sin(0)', '0', {type:'number'});
+test_math_used('tan(0)', '0', {type:'number'});
+
+// Test pi
+test_math_used('calc(sin(pi/2 - pi/2) )', '0', {type:'number', approx:0.1});
+test_math_used('calc(cos(pi - 3.14159265358979323846) )', '1', {type:'number', approx:0.1});
+
+//Test e
+test_math_used('calc(cos(e - 2.7182818284590452354) )', '1', {type:'number', approx:0.1});
+
+//Test units
+test_math_used('calc(sin(30deg + 1.0471967rad ) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(cos(30deg - 0.523599rad ) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(sin(3.14159 / 2 + 1 - 1) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(sin(100grad) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(cos(0 / 2 + 1 - 1) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(tan(30deg + 0.261799rad ) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(tan(0.7853975rad ) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(tan(3.14159 / 4 + 1 - 1) )', '1', {type:'number', approx:0.1});
+test_math_used('calc(sin(0.25turn) )', '1', {type:'number', approx:0.1});
+
+//Test nesting
+test_math_used('calc(cos(sin(cos(pi) + 1)))', '1', {type:'number', approx:0.1});
+test_math_used('calc(sin(tan(pi/4)*pi/2) )', '1', {type:'number', approx:0.1});
+</script>
diff --git a/testing/web-platform/tests/css/css-values/sin-cos-tan-invalid.html b/testing/web-platform/tests/css/css-values/sin-cos-tan-invalid.html
new file mode 100644
index 0000000000..54887bf46c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/sin-cos-tan-invalid.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#angles">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<link rel="author" title="Seokho Song" href="seokho@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_angle(value) {
+ test_invalid_value('transform', `rotate(${value})`);
+}
+
+// Syntax checking
+test_invalid_angle('sin()');
+test_invalid_angle('sin( )');
+test_invalid_angle('sin(,)');
+test_invalid_angle('sin(1dag)');
+test_invalid_angle('sin(1deg, )');
+test_invalid_angle('sin(, 1deg)');
+test_invalid_angle('sin(1deg + )');
+test_invalid_angle('sin(1deg - )');
+test_invalid_angle('sin(1deg * )');
+test_invalid_angle('sin(1deg / )');
+test_invalid_angle('sin(1deg 2deg)');
+test_invalid_angle('sin(1deg, , 2deg)');
+test_invalid_angle('cos()');
+test_invalid_angle('cos( )');
+test_invalid_angle('cos(,)');
+test_invalid_angle('cos(1dag)');
+test_invalid_angle('cos(1deg, )');
+test_invalid_angle('cos(, 1deg)');
+test_invalid_angle('cos(1deg + )');
+test_invalid_angle('cos(1deg - )');
+test_invalid_angle('cos(1deg * )');
+test_invalid_angle('cos(1deg / )');
+test_invalid_angle('cos(1deg 2deg)');
+test_invalid_angle('cos(1deg, , 2deg)');
+test_invalid_angle('tan()');
+test_invalid_angle('tan( )');
+test_invalid_angle('tan(,)');
+test_invalid_angle('tan(1dag)');
+test_invalid_angle('tan(1deg, )');
+test_invalid_angle('tan(, 1deg)');
+test_invalid_angle('tan(1deg + )');
+test_invalid_angle('tan(1deg - )');
+test_invalid_angle('tan(1deg * )');
+test_invalid_angle('tan(1deg / )');
+test_invalid_angle('tan(1deg 2deg)');
+test_invalid_angle('tan(1deg, , 2deg)');
+test_invalid_angle('sin(90px)');
+test_invalid_angle('sin(30deg + 1.0471967rad, 0)');
+test_invalid_angle('cos( 0 ,)');
+test_invalid_angle('cos( () 30deg - 0.523599rad )');
+test_invalid_angle('tan(45deg )');
+test_invalid_angle('tan(30deg, + 0.261799rad)');
+</script>
diff --git a/testing/web-platform/tests/css/css-values/sin-cos-tan-serialize.html b/testing/web-platform/tests/css/css-values/sin-cos-tan-serialize.html
new file mode 100644
index 0000000000..72287d6f3c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/sin-cos-tan-serialize.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Apple Inc">
+<link rel="author" title="Seokho Song" href="seokho@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(specified, expected, {prop="transform"}={}) {
+ test_specified_serialization(prop, `scale(${specified})`, `scale(${expected})`)
+}
+//TEST CASE | EXPECTED
+var test_map = {
+ "cos(0)" :"calc(1)",
+ "sin(0)" :"calc(0)",
+ "tan(0)" :"calc(0)",
+ "calc(sin(0) + 0.5)" :"calc(0.5)",
+ "calc(sin(0) + cos(0) + tan(0))" :"calc(1)",
+ "calc(cos(0) + 0.5)" :"calc(1.5)",
+ "calc(tan(0) + 0.5)" :"calc(0.5)",
+ "cos(0deg)" :"calc(1)",
+ "sin(0deg)" :"calc(0)",
+ "tan(0deg)" :"calc(0)",
+ "sin(30deg)" :"calc(0.5)",
+ "sin(0.523599)" :"calc(0.5)",
+ "sin(0.523599rad)" :"calc(0.5)",
+ "sin(33.333333grad)" :"calc(0.5)",
+ "sin(0.08333333turn)" :"calc(0.5)",
+ "cos(60deg)" :"calc(0.5)",
+ "cos(66.66666666grad)" :"calc(0.5)",
+ "cos(1.047197551)" :"calc(0.5)",
+ "cos(1.047197551rad)" :"calc(0.5)",
+ "cos(0.16666666666turn)" :"calc(0.5)",
+ "tan(45deg)" :"calc(1)",
+ "tan(50grad)" :"calc(1)",
+ "tan(0.78539816)" :"calc(1)",
+ "tan(0.78539816rad)" :"calc(1)",
+ "tan(0.125turn)" :"calc(1)",
+ "tan(90deg)" :"calc(infinity)",
+ "tan(-90deg)" :"calc(-infinity)",
+ "calc(sin(30deg) + cos(60deg) + tan(45deg))" :"calc(2)",
+ "calc(sin(infinity))" :"calc(NaN)",
+ "calc(cos(infinity))" :"calc(NaN)",
+ "calc(tan(infinity))" :"calc(NaN)",
+ "calc(sin(-infinity))" :"calc(NaN)",
+ "calc(cos(-infinity))" :"calc(NaN)",
+ "calc(tan(-infinity))" :"calc(NaN)",
+};
+
+for (var exp in test_map) {
+ test_serialization(exp, test_map[exp]);
+ test_serialization(`calc(${exp})`, test_map[exp]);
+}
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/support/1x1-green.png b/testing/web-platform/tests/css/css-values/support/1x1-green.png
new file mode 100644
index 0000000000..b98ca0ba0a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/1x1-green.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/1x1-lime.png b/testing/web-platform/tests/css/css-values/support/1x1-lime.png
new file mode 100644
index 0000000000..cb397fb090
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/1x1-lime.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/1x1-maroon.png b/testing/web-platform/tests/css/css-values/support/1x1-maroon.png
new file mode 100644
index 0000000000..3f86b07219
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/1x1-maroon.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/1x1-navy.png b/testing/web-platform/tests/css/css-values/support/1x1-navy.png
new file mode 100644
index 0000000000..9b9a03955b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/1x1-navy.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/1x1-red.png b/testing/web-platform/tests/css/css-values/support/1x1-red.png
new file mode 100644
index 0000000000..6bd73ac101
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/1x1-red.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/1x1-white.png b/testing/web-platform/tests/css/css-values/support/1x1-white.png
new file mode 100644
index 0000000000..dd43faec54
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/1x1-white.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/60x60-gg-rr.png b/testing/web-platform/tests/css/css-values/support/60x60-gg-rr.png
new file mode 100644
index 0000000000..84f5b2a4f1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/60x60-gg-rr.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/60x60-green.png b/testing/web-platform/tests/css/css-values/support/60x60-green.png
new file mode 100644
index 0000000000..b3c8cf3eb4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/60x60-green.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/README b/testing/web-platform/tests/css/css-values/support/README
new file mode 100644
index 0000000000..2e5f2ad073
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/README
@@ -0,0 +1,28 @@
+CSS Global Support Directory
+============================
+
+This directory contains common support files (such as images and external
+style sheets). These are sync'ed into the support directories of all our
+test suites. If you have test-suite-specific support files, please add
+them to the appropriate test-suite-specific support/ directory.
+
+If you add to a support/ directory, please run the tools/supportprop.py
+script from the top of the repository to cascade support files into the
+lower-level support directories.
+
+Description of the Common Support File Collection
+-------------------------------------------------
+
+The 1x1-* images are all exactly one pixel.
+
+The swatch-* images all use 15x15 cells.
+
+The square-* images all use 15x15 cells with one pixel borders.
+
+The pattern-* images use cells of various sizes:
+
+ pattern-grg-rgr-grg.png 20x20
+ pattern-rgr-grg-rgr.png 20x20
+ pattern-tr.png 15x15
+ pattern-grg-rrg-rgg.png 15x15
+
diff --git a/testing/web-platform/tests/css/css-values/support/a-green.css b/testing/web-platform/tests/css/css-values/support/a-green.css
new file mode 100644
index 0000000000..b0dbb071d5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/a-green.css
@@ -0,0 +1 @@
+.a { color: green; }
diff --git a/testing/web-platform/tests/css/css-values/support/b-green.css b/testing/web-platform/tests/css/css-values/support/b-green.css
new file mode 100644
index 0000000000..a0473f5ca2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/b-green.css
@@ -0,0 +1 @@
+.b { color: green; } \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/support/blue-32x32.png b/testing/web-platform/tests/css/css-values/support/blue-32x32.png
new file mode 100644
index 0000000000..deefd19b2a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/blue-32x32.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/c-red.css b/testing/web-platform/tests/css/css-values/support/c-red.css
new file mode 100644
index 0000000000..d4ba5c64e9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/c-red.css
@@ -0,0 +1 @@
+.c { color: red; } \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/support/cat.png b/testing/web-platform/tests/css/css-values/support/cat.png
new file mode 100644
index 0000000000..85dd732481
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/cat.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/import-green.css b/testing/web-platform/tests/css/css-values/support/import-green.css
new file mode 100644
index 0000000000..537104e663
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/import-green.css
@@ -0,0 +1 @@
+.import { color: green; }
diff --git a/testing/web-platform/tests/css/css-values/support/import-red.css b/testing/web-platform/tests/css/css-values/support/import-red.css
new file mode 100644
index 0000000000..9945ef4711
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/import-red.css
@@ -0,0 +1 @@
+.import { color: red; }
diff --git a/testing/web-platform/tests/css/css-values/support/mixed-units-01.html b/testing/web-platform/tests/css/css-values/support/mixed-units-01.html
new file mode 100644
index 0000000000..6401cd9b4b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/mixed-units-01.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style>
+ body {
+ margin: 0;
+ font-size: 16px;
+ }
+ .box {
+ background: rgb(0, 0, 255);
+ width: 100%;
+ height: 10px;
+ }
+
+ @media (width: calc(116px - 1em)) {
+ .box {
+ background: rgb(255, 165, 0);
+ }
+ }
+ </style>
+ </head>
+ <div class="box"></div>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/support/mixed-units-02.html b/testing/web-platform/tests/css/css-values/support/mixed-units-02.html
new file mode 100644
index 0000000000..67088c64c5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/mixed-units-02.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style>
+ body {
+ margin: 0;
+ font-size: 16px;
+ }
+ .box {
+ background: rgb(0, 0, 255);
+ width: 100%;
+ height: 10px;
+ }
+
+ @media (width: calc(200vh + 5em)) {
+ .box {
+ background: rgb(255, 165, 0);
+ }
+ }
+ </style>
+ </head>
+ <div class="box"></div>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/support/mixed-units-03.html b/testing/web-platform/tests/css/css-values/support/mixed-units-03.html
new file mode 100644
index 0000000000..3d614d395a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/mixed-units-03.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style>
+ body {
+ margin: 0;
+ font-size: 16px;
+ }
+ .box {
+ background: rgb(0, 0, 255);
+ width: 100%;
+ height: 10px;
+ }
+
+ @media (height: calc(100vw - 5.625em)) {
+ .box {
+ background: rgb(255, 165, 0);
+ }
+ }
+ </style>
+ </head>
+ <div class="box"></div>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/support/mixed-units-04.html b/testing/web-platform/tests/css/css-values/support/mixed-units-04.html
new file mode 100644
index 0000000000..b23c0e6a7f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/mixed-units-04.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style>
+ body {
+ margin: 0;
+ font-size: 16px;
+ }
+ .box {
+ background: rgb(0, 0, 255);
+ width: 100%;
+ height: 10px;
+ }
+
+ @media (width: calc(10vw + 900vh)) {
+ .box {
+ background: rgb(255, 165, 0);
+ }
+ }
+ </style>
+ </head>
+ <div class="box"></div>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/support/mixed-units-05.html b/testing/web-platform/tests/css/css-values/support/mixed-units-05.html
new file mode 100644
index 0000000000..e6196d3e31
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/mixed-units-05.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style>
+ body {
+ margin: 0;
+ font-size: 16px;
+ }
+ .box {
+ background: rgb(0, 0, 255);
+ width: 100%;
+ height: 10px;
+ }
+
+ @media (width: calc(900vh + 10px)) {
+ .box {
+ background: rgb(255, 165, 0);
+ }
+ }
+ </style>
+ </head>
+ <div class="box"></div>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/support/mixed-units-06.html b/testing/web-platform/tests/css/css-values/support/mixed-units-06.html
new file mode 100644
index 0000000000..a4a614f8d2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/mixed-units-06.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <style>
+ body {
+ margin: 0;
+ font-size: 16px;
+ }
+ .box {
+ background: rgb(0, 0, 255);
+ width: 100%;
+ height: 10px;
+ }
+
+ @media (width: calc(90vw + 10px)) {
+ .box {
+ background: rgb(255, 165, 0);
+ }
+ }
+ </style>
+ </head>
+ <div class="box"></div>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/support/pattern-grg-rgr-grg.png b/testing/web-platform/tests/css/css-values/support/pattern-grg-rgr-grg.png
new file mode 100644
index 0000000000..9b88fbd811
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/pattern-grg-rgr-grg.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/pattern-grg-rrg-rgg.png b/testing/web-platform/tests/css/css-values/support/pattern-grg-rrg-rgg.png
new file mode 100644
index 0000000000..fcf4f3fd7d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/pattern-grg-rrg-rgg.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/pattern-rgr-grg-rgr.png b/testing/web-platform/tests/css/css-values/support/pattern-rgr-grg-rgr.png
new file mode 100644
index 0000000000..d454e3a630
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/pattern-rgr-grg-rgr.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/pattern-tr.png b/testing/web-platform/tests/css/css-values/support/pattern-tr.png
new file mode 100644
index 0000000000..8b4b25364e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/pattern-tr.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/ruler-h-50%.png b/testing/web-platform/tests/css/css-values/support/ruler-h-50%.png
new file mode 100644
index 0000000000..cf2eea6b43
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/ruler-h-50%.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/ruler-h-50px.png b/testing/web-platform/tests/css/css-values/support/ruler-h-50px.png
new file mode 100644
index 0000000000..9f46583665
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/ruler-h-50px.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/ruler-v-100px.png b/testing/web-platform/tests/css/css-values/support/ruler-v-100px.png
new file mode 100644
index 0000000000..a837eca222
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/ruler-v-100px.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/ruler-v-50px.png b/testing/web-platform/tests/css/css-values/support/ruler-v-50px.png
new file mode 100644
index 0000000000..8414102802
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/ruler-v-50px.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/square-purple.png b/testing/web-platform/tests/css/css-values/support/square-purple.png
new file mode 100644
index 0000000000..0f522d7872
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/square-purple.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/square-teal.png b/testing/web-platform/tests/css/css-values/support/square-teal.png
new file mode 100644
index 0000000000..e567f51b91
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/square-teal.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/square-white.png b/testing/web-platform/tests/css/css-values/support/square-white.png
new file mode 100644
index 0000000000..5853cbb238
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/square-white.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/support/README b/testing/web-platform/tests/css/css-values/support/support/README
new file mode 100644
index 0000000000..ea8cb9ef35
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/support/README
@@ -0,0 +1,4 @@
+The swatch-green.png file in this directory is really a RED swatch,
+and the swatch-red.png file is really a green swatch.
+
+This directory is used to test relative URIs. \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/support/support/swatch-green.png b/testing/web-platform/tests/css/css-values/support/support/swatch-green.png
new file mode 100644
index 0000000000..1caf25c992
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/support/swatch-green.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/support/swatch-red.png b/testing/web-platform/tests/css/css-values/support/support/swatch-red.png
new file mode 100644
index 0000000000..0aa79b0c86
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/support/swatch-red.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/swatch-blue.png b/testing/web-platform/tests/css/css-values/support/swatch-blue.png
new file mode 100644
index 0000000000..bf2759634d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/swatch-blue.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/swatch-green.png b/testing/web-platform/tests/css/css-values/support/swatch-green.png
new file mode 100644
index 0000000000..0aa79b0c86
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/swatch-green.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/swatch-lime.png b/testing/web-platform/tests/css/css-values/support/swatch-lime.png
new file mode 100644
index 0000000000..55fd7fdaed
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/swatch-lime.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/swatch-orange.png b/testing/web-platform/tests/css/css-values/support/swatch-orange.png
new file mode 100644
index 0000000000..d3cd498b52
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/swatch-orange.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/swatch-red.png b/testing/web-platform/tests/css/css-values/support/swatch-red.png
new file mode 100644
index 0000000000..1caf25c992
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/swatch-red.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/swatch-teal.png b/testing/web-platform/tests/css/css-values/support/swatch-teal.png
new file mode 100644
index 0000000000..0293ce89de
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/swatch-teal.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/swatch-white.png b/testing/web-platform/tests/css/css-values/support/swatch-white.png
new file mode 100644
index 0000000000..1a7d4323d7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/swatch-white.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/swatch-yellow.png b/testing/web-platform/tests/css/css-values/support/swatch-yellow.png
new file mode 100644
index 0000000000..1591aa0e2e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/swatch-yellow.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/test-bl.png b/testing/web-platform/tests/css/css-values/support/test-bl.png
new file mode 100644
index 0000000000..904e24e996
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/test-bl.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/test-br.png b/testing/web-platform/tests/css/css-values/support/test-br.png
new file mode 100644
index 0000000000..f413ff5c1a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/test-br.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/test-inner-half-size.png b/testing/web-platform/tests/css/css-values/support/test-inner-half-size.png
new file mode 100644
index 0000000000..e473bf80ef
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/test-inner-half-size.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/test-outer.png b/testing/web-platform/tests/css/css-values/support/test-outer.png
new file mode 100644
index 0000000000..82eeace7fc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/test-outer.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/test-tl.png b/testing/web-platform/tests/css/css-values/support/test-tl.png
new file mode 100644
index 0000000000..f6ac0ef7e8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/test-tl.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/test-tr.png b/testing/web-platform/tests/css/css-values/support/test-tr.png
new file mode 100644
index 0000000000..59843ae54b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/test-tr.png
Binary files differ
diff --git a/testing/web-platform/tests/css/css-values/support/vh-support-transform-origin-iframe.html b/testing/web-platform/tests/css/css-values/support/vh-support-transform-origin-iframe.html
new file mode 100644
index 0000000000..ce3d4f0c68
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/vh-support-transform-origin-iframe.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewports units are supported in transform properties (iframe)
+ </title>
+ <meta name="assert" content="
+ Viewports units are supported in transform properties (translate)
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <link rel="help" href="http://www.w3.org/TR/css3-2d-transforms/#css-values">
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; overflow: hidden; }
+
+ html { background: green; }
+ #target, #over-target {
+ position: absolute; top: 0px; left: 0px;
+ width: 100px; height: 100px;
+ transform: scale(0.5);
+ }
+
+ #target {
+ background: red;
+ transform-origin: 200px 200px;
+ }
+
+ #over-target {
+ background: green;
+ transform-origin: 50vw 50vh;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+ <div id="over-target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/support/vh-support-transform-translate-iframe.html b/testing/web-platform/tests/css/css-values/support/vh-support-transform-translate-iframe.html
new file mode 100644
index 0000000000..f0b1b54c12
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/vh-support-transform-translate-iframe.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewports units are supported in transform properties (iframe)
+ </title>
+ <meta name="assert" content="
+ Viewports units are supported in transform properties (translate)
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <link rel="help" href="http://www.w3.org/TR/css3-2d-transforms/#css-values">
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; overflow: hidden; }
+
+ html { background: green; }
+ #target, #over-target {
+ position: absolute; top: 0px; left: 0px;
+ width: 100px; height: 100px;
+ }
+
+ #target {
+ background: red;
+ transform: translate(200px, 200px);
+ }
+
+ #over-target {
+ background: green;
+ transform: translate(50vw, 50vh);
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+ <div id="over-target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/support/vh_not_refreshing_on_chrome_iframe.html b/testing/web-platform/tests/css/css-values/support/vh_not_refreshing_on_chrome_iframe.html
new file mode 100644
index 0000000000..8d8e9b49d4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/support/vh_not_refreshing_on_chrome_iframe.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<!-- Submitted from TestTWF Paris -->
+<head>
+
+ <title>CSS Values and Units Test: vh-based dimension doesn't change when the element other dimension doesn't change.</title>
+
+ <style type="text/css">
+
+ * { margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; font-size: 13px; }
+
+ /* the first test box has its vertical dimension is set to some vh units */
+ #testBoxWithVhOnly { background: #F00; width: 60px; height: 20vh; float: left; }
+
+ /* the second test box, with fixed height */
+ #testBoxNotGrownHorizontallyByJS { background: #F0F; width: 20vh; height: 60px; float: left; }
+
+ /* third box, changed by using CSS transition */
+ #testBoxWithTransition { background: #FF0; width: 20vh; height: 40px; float: left;
+ transition-property: width, height;
+ transition-duration: 0.3s;
+ transition-delay: 0;
+ }
+
+ /* the reference box, growing in both directions (height by js, width by vh unit */
+ #referenceBoxGrownHorizontallyByJS { background: #0F0; width: 20vh; height: 40px; float: left; }
+
+ p { clear: both; margin: 10px 0; }
+
+ </style>
+
+</head>
+<body>
+
+<p>
+ All boxes should end up the same size. The green box is the reference one.
+</p>
+
+<div id="testBoxWithVhOnly"></div>
+<div id="testBoxNotGrownHorizontallyByJS"></div>
+<div id="testBoxWithTransition"></div>
+<div id="referenceBoxGrownHorizontallyByJS"></div>
+
+<script type="text/javascript">
+ 'use strict';
+
+ // In case this file was opened by mistake, redirects to proper test
+ if (window.top.location.href === document.location.href) {
+
+ window.top.location.href = "vh_not_refreshing_on_chrome.html";
+
+ }
+
+ function setDimension(id, dimension, value) {
+
+ var element = document.getElementById(id);
+
+ element.style[dimension] = value + "px";
+
+ }
+
+ function animate() {
+
+ var viewportHeight = document.documentElement.clientHeight;
+
+ var sizeH = 20;
+
+ var referenceDimension = Math.round(sizeH * viewportHeight / 100);
+
+ setDimension('referenceBoxGrownHorizontallyByJS', 'height', referenceDimension);
+
+ if (referenceDimension < 60) {
+ setTimeout(animate, 20);
+ } else {
+ parent.postMessage('referenceBoxGrownHorizontallyByJS', '*');
+ }
+ }
+
+ setTimeout(animate, 20);
+
+ addEventListener('transitionend', event => {
+ if (event.propertyName == 'width') {
+ // Stop any further transitons.
+ testBoxWithTransition.style.transitionProperty = 'none';
+ parent.postMessage('testBoxWithTransition', '*');
+ }
+ }, false);
+ var transitionedTestBoxStyle = document.getElementById('testBoxWithTransition').style;
+ transitionedTestBoxStyle.height = "60px";
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/update-subpixel-rem-unit.html b/testing/web-platform/tests/css/css-values/update-subpixel-rem-unit.html
new file mode 100644
index 0000000000..98d4f00f92
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/update-subpixel-rem-unit.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html style="font-size:16px">
+<head>
+ <title>CSS Values and Units Test: rem subpixel change</title>
+ <link rel="help" href="https://drafts.csswg.org/css-values/#rem">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div style="font-size:16px">
+ <div id="remElement" style="width: 10rem"></div>
+ </div>
+ <script>
+ test(() => {
+ assert_equals(getComputedStyle(remElement).width, "160px");
+ document.documentElement.style.fontSize = "16.1px";
+ assert_equals(getComputedStyle(remElement).width, "161px");
+ }, "Check that a 0.1px change in root font-size affect rem units.");
+ </script>
+<body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/urls/empty.html b/testing/web-platform/tests/css/css-values/urls/empty.html
new file mode 100644
index 0000000000..3748567545
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/urls/empty.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>Empty URLs behaviour</title>
+<link rel=help href=https://drafts.csswg.org/css-values/#url-empty>
+<link rel=help href=https://github.com/w3c/csswg-drafts/issues/2211#issuecomment-365677844>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+#inline-unquoted {
+ background-image: url();
+ cursor: url(), pointer;
+}
+
+#inline-quoted {
+ background-image: url("");
+ cursor: url(""), pointer;
+}
+</style>
+<link rel=stylesheet href=support/empty-urls.css>
+<div id="inline-unquoted"></div>
+<div id="inline-quoted"></div>
+<div id="external-unquoted"></div>
+<div id="external-quoted"></div>
+<script>
+const ids = [
+ "inline-unquoted",
+ "inline-quoted",
+ "external-unquoted",
+ "external-quoted"
+];
+
+for (let id of ids) {
+ test(function() {
+ const el = document.getElementById(id);
+ const style = window.getComputedStyle(el);
+ assert_equals(style["background-image"], 'url("")');
+ assert_equals(style["cursor"], 'url(""), pointer');
+ }, "empty URL: " + id);
+}
+</script>
diff --git a/testing/web-platform/tests/css/css-values/urls/fragment-only.html b/testing/web-platform/tests/css/css-values/urls/fragment-only.html
new file mode 100644
index 0000000000..a7153adf8f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/urls/fragment-only.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<title>Fragment-on URLs behaviour</title>
+<link rel=help href=https://drafts.csswg.org/css-values/#local-urls>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+#inline-unquoted {
+ background-image: url(#foo);
+ cursor: url(#foo), pointer;
+}
+
+#inline-quoted {
+ background-image: url("#foo");
+ cursor: url("#foo"), pointer;
+}
+</style>
+<link rel=stylesheet href=support/fragment-only-urls.css>
+<div id="inline-unquoted"></div>
+<div id="inline-quoted"></div>
+<div id="external-unquoted"></div>
+<div id="external-quoted"></div>
+<div id="external-variable"></div>
+<script>
+const ids = [
+ "inline-unquoted",
+ "inline-quoted",
+ "external-unquoted",
+ "external-quoted",
+ "external-variable",
+];
+
+for (let id of ids) {
+ test(function() {
+ const el = document.getElementById(id);
+ const style = window.getComputedStyle(el);
+ assert_equals(style["background-image"], 'url("#foo")');
+ assert_equals(style["cursor"], 'url("#foo"), pointer');
+ }, "empty URL: " + id);
+}
+</script>
diff --git a/testing/web-platform/tests/css/css-values/urls/resolve-relative-to-base.sub.html b/testing/web-platform/tests/css/css-values/urls/resolve-relative-to-base.sub.html
new file mode 100644
index 0000000000..bfbe127ab2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/urls/resolve-relative-to-base.sub.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<title>URLs in embedded style sheets resolve relative to the document base URI</title>
+<link rel=help href=https://drafts.csswg.org/css-values/#relative-urls>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<base href="http://{{hosts[alt][www]}}">
+<style>
+:root {
+ --image-path: url("images/test.png");
+}
+#relative-image-url {
+ background-image: url(images/test.png);
+}
+
+#relative-image-variable-url {
+ background-image: var(--image-path);
+}
+</style>
+<div id="relative-image-url"></div>
+<div id="relative-image-variable-url"></div>
+<script>
+const ids = [
+ "relative-image-url",
+ "relative-image-variable-url"
+];
+
+for (let id of ids) {
+ test(() => {
+ const el = document.getElementById(id);
+ const backgroundImageStyle = window.getComputedStyle(el)["background-image"];
+ const baseRelativeImageURL = new URL("images/test.png", document.baseURI);
+ assert_equals(backgroundImageStyle, `url("${baseRelativeImageURL.href}")`);
+ }, "base-relative URL: " + id);
+}
+</script>
diff --git a/testing/web-platform/tests/css/css-values/urls/resolve-relative-to-stylesheet.html b/testing/web-platform/tests/css/css-values/urls/resolve-relative-to-stylesheet.html
new file mode 100644
index 0000000000..1475d97052
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/urls/resolve-relative-to-stylesheet.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>URLs in a stylesheet resolve relative to the stylesheet</title>
+<link rel=help href=https://drafts.csswg.org/css-values/#relative-urls>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<link id="stylesheet" rel=stylesheet href=support/relative-urls.css>
+<div id="stylesheet-relative-image"></div>
+<div id="stylesheet-relative-variable-image"></div>
+<div id="stylesheet-relative-document-variable-image"></div>
+<style>
+ :root {
+ --image-path-document: url("images/test.png");
+ }
+</style>
+<script>
+const ids = [
+ "stylesheet-relative-image",
+ "stylesheet-relative-variable-image",
+ "stylesheet-relative-document-variable-image",
+];
+
+for (let id of ids) {
+ test(() => {
+ const el = document.getElementById(id);
+ const backgroundImageStyle = window.getComputedStyle(el)["background-image"];
+
+ const stylesheet = document.getElementById("stylesheet");
+ const sheetRelativeImageURL = new URL("images/test.png", stylesheet.href);
+
+ assert_equals(backgroundImageStyle, `url("${sheetRelativeImageURL.href}")`);
+ }, "stylesheet-relative URL: " + id);
+}
+</script>
diff --git a/testing/web-platform/tests/css/css-values/urls/support/empty-urls.css b/testing/web-platform/tests/css/css-values/urls/support/empty-urls.css
new file mode 100644
index 0000000000..0559e3b235
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/urls/support/empty-urls.css
@@ -0,0 +1,9 @@
+#external-unquoted {
+ background-image: url();
+ cursor: url(), pointer;
+}
+
+#external-quoted {
+ background-image: url("");
+ cursor: url(""), pointer;
+}
diff --git a/testing/web-platform/tests/css/css-values/urls/support/fragment-only-urls.css b/testing/web-platform/tests/css/css-values/urls/support/fragment-only-urls.css
new file mode 100644
index 0000000000..2c39a087e9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/urls/support/fragment-only-urls.css
@@ -0,0 +1,19 @@
+:root {
+ --fragment-image-url: url("#foo");
+ --fragment-cursor-url: url("#foo"), pointer;
+}
+
+#external-unquoted {
+ background-image: url(#foo);
+ cursor: url(#foo), pointer;
+}
+
+#external-quoted {
+ background-image: url("#foo");
+ cursor: url("#foo"), pointer;
+}
+
+#external-variable {
+ background-image: var(--fragment-image-url);
+ cursor: var(--fragment-cursor-url);
+}
diff --git a/testing/web-platform/tests/css/css-values/urls/support/relative-urls.css b/testing/web-platform/tests/css/css-values/urls/support/relative-urls.css
new file mode 100644
index 0000000000..1354c655e9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/urls/support/relative-urls.css
@@ -0,0 +1,15 @@
+:root {
+ --image-path-stylesheet: url("images/test.png");
+}
+
+#stylesheet-relative-image {
+ background-image: url(images/test.png);
+}
+
+#stylesheet-relative-variable-image {
+ background-image: var(--image-path-stylesheet);
+}
+
+#stylesheet-relative-document-variable-image {
+ background-image: var(--image-path-document);
+}
diff --git a/testing/web-platform/tests/css/css-values/vh-calc-support-pct.html b/testing/web-platform/tests/css/css-values/vh-calc-support-pct.html
new file mode 100644
index 0000000000..3a422d4ce4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-calc-support-pct.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewport units are supported inside calc expressions.
+ </title>
+ <meta name="assert" content="
+ Check that viewport units add correctly to percentages in calc() expressions
+ " />
+
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; }
+ #target { position: absolute; background: green; width: calc(100vw + 50%); height: calc(100vh + 50%); top: -50%; left: -50%; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-calc-support.html b/testing/web-platform/tests/css/css-values/vh-calc-support.html
new file mode 100644
index 0000000000..0e98941ab4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-calc-support.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewport units are supported inside calc expressions.
+ </title>
+ <meta name="assert" content="
+ Check that viewport units add correctly to pixels in calc() expressions
+ " />
+
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ />
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; }
+ #target { position: absolute; background: green; width: calc(100vw + 50px); height: calc(100vh + 50px); top: -50px; left: -50px; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-em-inherit.html b/testing/web-platform/tests/css/css-values/vh-em-inherit.html
new file mode 100644
index 0000000000..1affbd093d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-em-inherit.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ 0vh and 0vw are correctly treated as 0px
+ </title>
+ <meta name="assert" content="
+ 0vh and 0vw are correctly treated as 0px
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; font-size: 100vw; }
+ #target { background: green; width: 1rem; height: 1em; font-size: 100vh; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-inherit.html b/testing/web-platform/tests/css/css-values/vh-inherit.html
new file mode 100644
index 0000000000..99890e309c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-inherit.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewport units are inherited properly
+ </title>
+ <meta name="assert" content="
+ Viewport units are inherited properly
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; }
+ #outer { position: relative; background: green; width: 50vw; height: 100vh; }
+ #inner { position: absolute; background: green; left: 100%; width: inherit; height: inherit; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"><div id="inner"></div></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-interpolate-pct.html b/testing/web-platform/tests/css/css-values/vh-interpolate-pct.html
new file mode 100644
index 0000000000..293d686c84
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-interpolate-pct.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewport units are interpolated correctly
+ </title>
+ <meta name="assert" content="
+ The interpolated size mid-way between 0px and 200vh is 100vh (respectively for vw)
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths"/>
+ <link rel="help" href="http://www.w3.org/TR/css3-animations/#animations"/>
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ @keyframes anim {
+ from { width: 0%; height: 0%; }
+ to { width: 200vw; height: 200vh; }
+ }
+
+ html, body { margin: 0px; padding: 0px; height: 100%; }
+
+ html { background: red; overflow: hidden; }
+ #outer { position: relative; background: green; }
+ #outer { animation: anim 2000000s; animation-delay: -1000000s; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-interpolate-px.html b/testing/web-platform/tests/css/css-values/vh-interpolate-px.html
new file mode 100644
index 0000000000..f071357434
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-interpolate-px.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewport units are interpolated correctly
+ </title>
+ <meta name="assert" content="
+ The interpolated size mid-way between 0px and 200vh is 100vh (respectively for vw)
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths"/>
+ <link rel="help" href="http://www.w3.org/TR/css3-animations/#animations"/>
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ @keyframes anim {
+ from { width: 0px; height: 0px; }
+ to { width: 200vw; height: 200vh; }
+ }
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; overflow: hidden; }
+ #outer { position: relative; background: green; }
+ #outer { animation: anim 2000000s; animation-delay: -1000000s; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-interpolate-vh.html b/testing/web-platform/tests/css/css-values/vh-interpolate-vh.html
new file mode 100644
index 0000000000..d6671174ef
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-interpolate-vh.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewport units are interpolated correctly
+ </title>
+ <meta name="assert" content="
+ The interpolated size mid-way between 75vh and 125vh is 100vh (respectively for vw)
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths"/>
+ <link rel="help" href="http://www.w3.org/TR/css3-animations/#animations"/>
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ @keyframes anim {
+ from { width: 75vw; height: 75vh; }
+ to { width: 125vw; height: 125vh; }
+ }
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: red; overflow: hidden; }
+ #outer { position: relative; background: green; }
+ #outer { animation: anim 2000000s; animation-delay: -1000000s; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="outer"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-support-margin.html b/testing/web-platform/tests/css/css-values/vh-support-margin.html
new file mode 100644
index 0000000000..57fce2064b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-support-margin.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewports units are supported in margin properties
+ </title>
+ <meta name="assert" content="
+ Viewports units are supported in margin properties
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:francois.remy.pub@outlook.com"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; height: 100%; }
+
+ html { background: green; }
+ #target { background: red; width: 100%; height: 100%; margin-left: -100vw; margin-top: -100vh; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-support-transform-origin.html b/testing/web-platform/tests/css/css-values/vh-support-transform-origin.html
new file mode 100644
index 0000000000..38d17d2fdc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-support-transform-origin.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewports units are supported in transform properties
+ </title>
+ <meta name="assert" content="
+ Viewports units are supported in transform properties
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <link rel="help" href="http://www.w3.org/TR/css3-2d-transforms/#css-values">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; overflow: hidden; }
+
+ html { background: green; }
+ iframe { width: 400px; height: 400px; margin: 0px; padding: 0px; border: 0px none transparent; }
+
+ </style>
+
+</head>
+<body>
+
+ <iframe src="support/vh-support-transform-origin-iframe.html"></iframe>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-support-transform-translate.html b/testing/web-platform/tests/css/css-values/vh-support-transform-translate.html
new file mode 100644
index 0000000000..900b653d49
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-support-transform-translate.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewports units are supported in transform properties
+ </title>
+ <meta name="assert" content="
+ Viewports units are supported in transform properties (translate)
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <link rel="help" href="http://www.w3.org/TR/css3-2d-transforms/#css-values">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; overflow: hidden; }
+
+ html { background: green; }
+ iframe { width: 400px; height: 400px; margin: 0px; padding: 0px; border: 0px none transparent; }
+
+ </style>
+
+</head>
+<body>
+
+ <iframe src="support/vh-support-transform-translate-iframe.html"></iframe>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-support.html b/testing/web-platform/tests/css/css-values/vh-support.html
new file mode 100644
index 0000000000..c65b5493fe
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-support.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ Viewports units are supported in sizing properties
+ </title>
+ <meta name="assert" content="
+ Viewports units are supported in sizing properties
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ #target { background: green; width: 100vw; height: 100vh; }
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh-zero-support.html b/testing/web-platform/tests/css/css-values/vh-zero-support.html
new file mode 100644
index 0000000000..1c1bcd1761
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh-zero-support.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>
+ CSS Values and Units Test:
+ 0vh and 0vw are correctly treated as 0px
+ </title>
+ <meta name="assert" content="
+ 0vh and 0vw are correctly treated as 0px
+ " />
+
+ <link
+ rel="author"
+ title="François REMY"
+ href="mailto:fremycompany.developer@yahoo.fr"
+ / >
+
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+
+ <link
+ rel="match"
+ href="reference/all-green.html"
+ />
+
+ <style type="text/css">
+
+ html, body { margin: 0px; padding: 0px; }
+
+ html { background: green; }
+ #target { background: red; width: 0vw; height: 0vh; }
+
+ </style>
+
+</head>
+<body>
+
+ <div id="target"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/vh_not_refreshing_on_chrome.html b/testing/web-platform/tests/css/css-values/vh_not_refreshing_on_chrome.html
new file mode 100644
index 0000000000..e5606a0cb7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/vh_not_refreshing_on_chrome.html
@@ -0,0 +1,70 @@
+<!-- Submitted from TestTWF Paris -->
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+ <title>CSS Values and Units Test: vh-based dimension doesn't change when the element's other dimension doesn't change.</title>
+ <meta name="timeout" content="long">
+ <link rel="author" title="Marc Bourlon" href="mailto:marc@bourlon.com">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <link rel="match" href="reference/vh_not_refreshing_on_chrome-ref.html">
+ <meta charset="UTF-8">
+ <meta name="assert" content="vh-based dimension doesn't change when the element's other dimension doesn't change.">
+ <!-- This test exhibits a bug for Chrome 19.0.1084.56 / Mac OS X 10.6.8 -->
+ <script src="/common/reftest-wait.js"></script>
+
+ <style type="text/css">
+
+ * { margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; font-size: 13px; }
+
+ #frameTest { width: 600px; height: 200px; border: 1px solid #000; }
+
+ </style>
+
+ <script type="text/javascript">
+ 'use strict';
+
+ // We must not capture the screen until the frameTest, referenceBoxGrownHorizontallyByJS
+ // and testBoxWithTransition elements have finished changing height.
+ var elementsPending = 3;
+ function receiveMessage() {
+ if (--elementsPending === 0) {
+ takeScreenshot();
+ }
+ }
+
+ window.addEventListener('message', receiveMessage, false);
+
+ var height = 200;
+
+ function resizeReference() {
+
+ var frameTest = document.getElementById('frameTest');
+
+ // let's resize the iframe vertically only, showing that the vh sizes is not updated.
+ if (height < 300) {
+
+ //frameTest.style.width = height++ + "px";
+ frameTest.style.height = ++height + "px";
+
+ setTimeout(resizeReference, 10);
+
+ } else {
+
+ // uncomment the next line to see how a width resize triggers a layout recalculation
+ //frameTest.style.width = (parseInt(window.getComputedStyle(document.getElementById('frameTest'))['width'], 10) + 1) + "px";
+
+ window.postMessage('frameTest', '*');
+ }
+
+ }
+
+ setTimeout(resizeReference, 10);
+ </script>
+
+</head>
+<body>
+
+<iframe id="frameTest" src="support/vh_not_refreshing_on_chrome_iframe.html" frameborder="0"></iframe>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/viewport-relative-lengths-scaled-viewport.html b/testing/web-platform/tests/css/css-values/viewport-relative-lengths-scaled-viewport.html
new file mode 100644
index 0000000000..dba2af8fa0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-relative-lengths-scaled-viewport.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<!-- Submitted from TestTWF Paris -->
+ <head>
+ <title>CSS Values and Units Test: Viewport units in scaled viewport</title>
+ <meta charset="UTF-8">
+ <meta name="assert" content="viewport relative units scale with viewport.">
+ <link rel="author" title="Emil A Eklund" href="mailto:eae@chromium.org">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ iframe { border: 0; }
+ </style>
+ </head>
+ <body>
+ <div id="log"></div>
+ <iframe id="testFrame" src="javascript:void(0)"></iframe>
+ <script>
+ test(function() {
+ var frameElement = document.getElementById('testFrame');
+ var frameDocument = frameElement.contentDocument;
+
+ var testElement = frameDocument.createElement('div');
+ testElement.style.width = '50vw';
+ testElement.style.height = '50vh';
+ testElement.style.position = 'absolute';
+ testElement.style.left = '0';
+ testElement.style.top = '0';
+ testElement.style.backgroundColor = 'black';
+ frameDocument.body.appendChild(testElement);
+
+ var frameWidth = frameElement.getBoundingClientRect().width;
+ var frameHeight = frameElement.getBoundingClientRect().height;
+ for (var i = 1; i <= 200; i++) {
+ var scale = i / 100;
+ frameDocument.body.style.transform = 'scale(' + scale + ')';
+ var rect = testElement.getBoundingClientRect();
+ var actualWidth = rect.width;
+ var actualHeight = rect.height;
+ var expectedWidth = frameWidth * scale / 2;
+ var expectedHeight = frameHeight * scale / 2;
+
+ assert_approx_equals(actualWidth, expectedWidth, 0.1, '50vw at ' + scale + ' scale');
+ assert_approx_equals(actualHeight, expectedHeight, 0.1, '50vh at ' + scale + ' scale');
+ }
+ }, 'viewport relative units in scaled viewport');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/viewport-unit-011.html b/testing/web-platform/tests/css/css-values/viewport-unit-011.html
new file mode 100644
index 0000000000..055f3d1fd2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-unit-011.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+
+ <meta charset="UTF-8">
+
+ <title>CSS Values and Units Test: vh unit and vw unit (basic)</title>
+
+ <!--
+ Original test is:
+
+ https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/viewport-unit.html
+ -->
+
+ <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+ <link rel="help" href="https://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <link rel="match" href="reference/viewport-unit-011-ref.html">
+
+<style>
+body {
+ margin: 0;
+ height: 100vh;
+}
+div {
+ width: calc(50vw + 10%);
+ height: calc(50vh + 10%);
+ background-color: green;
+}
+</style>
+<div>
+</div> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-001-print-ref.html b/testing/web-platform/tests/css/css-values/viewport-units-001-print-ref.html
new file mode 100644
index 0000000000..bc914522c7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-001-print-ref.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS test reference</title>
+<style>
+ body { margin: 0 }
+ :root {
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
+ border: 1px solid black;
+ }
+</style>
+<div>I should not overflow to the next page.</div>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-001-print.html b/testing/web-platform/tests/css/css-values/viewport-units-001-print.html
new file mode 100644
index 0000000000..3bff494e53
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-001-print.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Viewport units in print account for margins</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1414600">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5437">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<link rel="match" href="viewport-units-001-print-ref.html">
+<style>
+ body { margin: 0 }
+ div {
+ box-sizing: border-box;
+ width: 100vw;
+ height: 100vh;
+ border: 1px solid black;
+ }
+</style>
+<div>I should not overflow to the next page.</div>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-after-font-load.html b/testing/web-platform/tests/css/css-values/viewport-units-after-font-load.html
new file mode 100644
index 0000000000..3bdd349971
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-after-font-load.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Values: Viewport units are computed correctly after font load.</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://www.w3.org/TR/css-values-3/#viewport-relative-lengths">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1620359">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe width=300 height=300 scrolling=no srcdoc=""></iframe>
+<script>
+let t = async_test("Viewport units are correctly updated after resize even if a font load has happened before");
+let iframe = document.querySelector("iframe");
+onload = t.step_func(function() {
+ let doc = iframe.contentDocument;
+ let win = iframe.contentWindow;
+ doc.body.innerHTML = `
+ <div style="width: 100vw; height: 100vh; background: green"></div>
+ `;
+ let div = doc.querySelector("div");
+ let oldWidth = win.getComputedStyle(div).width;
+ let oldHeight = win.getComputedStyle(div).height;
+ assert_equals(oldWidth, win.innerWidth + "px", "Should fill the viewport");
+ assert_equals(oldHeight, win.innerHeight + "px", "Should fill the viewport");
+ let link = doc.createElement("link");
+ link.rel = "stylesheet";
+ link.href = "/fonts/ahem.css";
+ link.onload = t.step_func(function() {
+ iframe.width = 400;
+ win.requestAnimationFrame(t.step_func(function() {
+ win.requestAnimationFrame(t.step_func_done(function() {
+ let newWidth = win.getComputedStyle(div).width;
+ let newHeight = win.getComputedStyle(div).height;
+ assert_equals(newWidth, win.innerWidth + "px", "Should fill the viewport");
+ assert_equals(newHeight, win.innerHeight + "px", "Should fill the viewport");
+ assert_equals(newHeight, oldHeight, "Height shouldn't have changed");
+ assert_not_equals(newWidth, oldWidth, "Width should have changed");
+ }));
+ }));
+ });
+ doc.body.appendChild(link);
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-compute.html b/testing/web-platform/tests/css/css-values/viewport-units-compute.html
new file mode 100644
index 0000000000..2f080d2aab
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-compute.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<title>Resolving viewport units</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ iframe {
+ width: 200px;
+ height: 100px;
+ }
+</style>
+
+<iframe id=iframe></iframe>
+
+<script>
+
+const doc = iframe.contentDocument;
+const win = iframe.contentWindow;
+
+function test_computed_value(value, expected) {
+ test((t) => {
+ t.add_cleanup(() => { doc.body.innerHTML = ''; });
+ doc.body.innerHTML = `
+ <!doctype html>
+ <style>
+ * { margin: 0; }
+ body { height: 100%; }
+ div { height: ${value}; }
+ </style>
+ <div></div>
+ `;
+ let div = doc.querySelector('div');
+ assert_equals(win.getComputedStyle(div).height, expected);
+ }, `${value} computes to ${expected}`);
+}
+
+test_computed_value('100vw', '200px');
+test_computed_value('100vi', '200px');
+test_computed_value('100vmax', '200px');
+test_computed_value('100svw', '200px');
+test_computed_value('100svi', '200px');
+test_computed_value('100svmax', '200px');
+test_computed_value('100lvw', '200px');
+test_computed_value('100lvi', '200px');
+test_computed_value('100lvmax', '200px');
+test_computed_value('100dvw', '200px');
+test_computed_value('100dvi', '200px');
+test_computed_value('100dvmax', '200px');
+
+test_computed_value('100vh', '100px');
+test_computed_value('100vb', '100px');
+test_computed_value('100vmin', '100px');
+test_computed_value('100svh', '100px');
+test_computed_value('100svb', '100px');
+test_computed_value('100svmin', '100px');
+test_computed_value('100lvh', '100px');
+test_computed_value('100lvb', '100px');
+test_computed_value('100lvmin', '100px');
+test_computed_value('100dvh', '100px');
+test_computed_value('100dvb', '100px');
+test_computed_value('100dvmin', '100px');
+
+test_computed_value('1dvw', '2px');
+test_computed_value('10dvw', '20px');
+test_computed_value('1dvh', '1px');
+test_computed_value('10dvh', '10px');
+
+test_computed_value('calc(1dvw + 1dvw)', '4px');
+test_computed_value('calc(1dvw + 1dvh)', '3px');
+test_computed_value('calc(1dvw + 100px)', '102px');
+test_computed_value('max(1svw, 1svh)', '2px');
+test_computed_value('min(1lvw, 1lvh)', '1px');
+test_computed_value('calc(1dvw + 10%)', '12px');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-css2-001.html b/testing/web-platform/tests/css/css-values/viewport-units-css2-001.html
new file mode 100644
index 0000000000..c51237dd8a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-css2-001.html
@@ -0,0 +1,234 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Values and Units Test: Checks viewport units against CSS 2.1 properties and the CSSOM</title>
+ <meta charset="UTF-8">
+ <meta name="assert" content="Testing what happens when one applies and rereads viewport unit lengths to CSS 2.1 properties that accept length values" />
+ <link rel="author" title="Christian Schaefer" href="mailto:schaepp@gmx.de">
+ <link rel="help" href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ #div {
+ position: relative;
+ width: 50vw;
+ height: 10vw;
+ background: green;
+ border: 0 green solid;
+ font-size: 4vw;
+ }
+
+ #table td {
+ border: 1px solid green;
+ }
+ </style>
+</head>
+<body>
+ <div id="log"></div>
+
+ <p>
+ Checks viewport units. Also re-check with zoom in/out.
+ </p>
+
+ <div id="div">
+ Test the Web Forward!
+ </div>
+
+ <table id="table">
+ <tbody>
+ <tr>
+ <td id="td">Test</td>
+ <td>T</td>
+ <td>W</td>
+ <td>F</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <script>
+
+ /* Boilerplate code */
+
+ var camelize = function (str) {
+ return str.replace(/\-(\w)/g, function(str, letter){
+ return letter.toUpperCase();
+ });
+ };
+
+ var retrieveComputedStyle = function(element,property){
+ var result =
+ document
+ .defaultView
+ .getComputedStyle(element,null)
+ .getPropertyValue(property);
+
+ // If there are multiple values, cut down to the first
+ result = result.split(' ')[0];
+
+ if(window.console) console.log('Retrieving ' + property + ' property. Result: ' + result);
+
+ return result;
+ }
+
+ var testit = function(element,vunit,property,expectedResult){
+
+ element.style[camelize(property)] = '0px';
+ element.style[camelize(property)] = lengthAmount + vunit;
+
+ if(window.console) console.log(element.nodeName.toLowerCase() + '.style.' + camelize(property) + ' = ' + lengthAmount + vunit);
+
+ var result = retrieveComputedStyle(element,property);
+
+ // Test against WebKit's getComputedStyle bug, where it does not return absolute values
+ // As required here: http://www.w3.org/TR/1998/REC-CSS2-19980512/cascade.html#computed-value
+ // If it returns a pixel value, but this value is 0px then it is considered a fail, too.
+ var px_result = result.search(/^[-\d\.]+px$/) !== -1 && result !== '0px' ? 'non-zero px-based value' : result;
+
+ // If browser returns pixel value, we compare against our expected pixel value
+ if(px_result === 'non-zero px-based value'){
+ test(function(){
+ assert_equals(Math.round(parseFloat(result.replace(/[^-\d\.]+/g,''))),expectedResult);
+ },vunit + ' length applied to ' + property);
+ }
+ // If not, we compare against the value we set initially
+ else {
+ test(function(){
+ assert_equals(result,lengthAmount + vunit);
+ },vunit + ' length applied to ' + property);
+ }
+
+ // Does the browser have a bug in getComputedStyle or not?
+ test(function(){
+ assert_equals(px_result,'non-zero px-based value');
+ },vunit + ' length applied to ' + property + ': getComputedStyle returns a non-zero px-based value');
+
+ element.style[camelize(property)] = '';
+ }
+
+ var lengthAmount = 10;
+ var layoutViewportWidth = document.documentElement.clientWidth;
+ var layoutViewportHeight = document.documentElement.clientHeight;
+
+ var viewportUnits = [
+ {
+ ident: 'vw',
+ expectedResult: Math.round(layoutViewportWidth * (lengthAmount / 100))
+ }
+ ,{
+ ident: 'vh',
+ expectedResult: Math.round(layoutViewportHeight * (lengthAmount / 100))
+ }
+ ,{
+ ident: 'vmin',
+ expectedResult: layoutViewportWidth < layoutViewportHeight ? Math.round(layoutViewportWidth * (lengthAmount / 100)) : Math.round(layoutViewportHeight * (lengthAmount / 100))
+ }
+ ,{
+ ident: 'vmax',
+ expectedResult: layoutViewportWidth > layoutViewportHeight ? Math.round(layoutViewportWidth * (lengthAmount / 100)) : Math.round(layoutViewportHeight * (lengthAmount / 100))
+ }
+ ]
+
+ // List of length accepting properties and which element they map to
+ // http://www.w3.org/TR/CSS21/propidx.html
+ var lengthAcceptingProperties = [
+ {
+ name: 'width',
+ element: 'div'
+ }
+ ,{
+ name: 'height',
+ element: 'div'
+ }
+ ,{
+ name: 'min-width',
+ element: 'div'
+ }
+ ,{
+ name: 'min-height',
+ element: 'div'
+ }
+ ,{
+ name: 'max-width',
+ element: 'div'
+ }
+ ,{
+ name: 'max-height',
+ element: 'div'
+ }
+ ,{
+ name: 'margin-top',
+ element: 'div'
+ }
+ ,{
+ name: 'padding-top',
+ element: 'div'
+ }
+ ,{
+ name: 'border-top-width',
+ element: 'div'
+ }
+ ,{
+ name: 'font-size',
+ element: 'div'
+ }
+ ,{
+ name: 'line-height',
+ element: 'div'
+ }
+ ,{
+ name: 'border-spacing',
+ element: 'table'
+ }
+ ,{
+ name: 'top',
+ element: 'div'
+ }
+ ,{
+ name: 'right',
+ element: 'div'
+ }
+ ,{
+ name: 'bottom',
+ element: 'div'
+ }
+ ,{
+ name: 'left',
+ element: 'div'
+ }
+ ,{
+ name: 'letter-spacing',
+ element: 'div'
+ }
+ ,{
+ name: 'text-indent',
+ element: 'div'
+ }
+ ,{
+ name: 'vertical-align',
+ element: 'td'
+ }
+ ,{
+ name: 'word-spacing',
+ element: 'div'
+ }
+ ];
+
+ var div = document.getElementById('div');
+ var table = document.getElementById('table');
+ var td = document.getElementById('td');
+
+ for(unitEntry in viewportUnits){
+ for(propertyEntry in lengthAcceptingProperties){
+
+ var vunit = viewportUnits[unitEntry].ident;
+ var expectedResult = viewportUnits[unitEntry].expectedResult;
+ var property = lengthAcceptingProperties[propertyEntry].name;
+ var element = window[lengthAcceptingProperties[propertyEntry].element];
+
+ testit(element,vunit,property,expectedResult);
+ }
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-invalidation.html b/testing/web-platform/tests/css/css-values/viewport-units-invalidation.html
new file mode 100644
index 0000000000..c7c980e04d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-invalidation.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<title>Invalidation of viewport units</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ iframe {
+ width: 200px;
+ height: 100px;
+ }
+
+ iframe.resize {
+ width: 400px;
+ height: 300px;
+ }
+</style>
+
+<main id=main></main>
+
+<script>
+
+function test_invalidation_value(value, expected_pre, expected_post) {
+ test((t) => {
+ let iframe = document.createElement('iframe');
+ main.append(iframe);
+ const doc = iframe.contentDocument;
+ const win = iframe.contentWindow;
+ t.add_cleanup(() => {
+ doc.body.innerHTML = '';
+ iframe.remove();
+ });
+ doc.body.innerHTML = `<div style="height: ${value};"></div>`;
+ let div = doc.querySelector('div');
+ assert_equals(win.getComputedStyle(div).height, expected_pre);
+
+ t.add_cleanup(() => { iframe.classList.remove('resize'); })
+ iframe.classList.add('resize');
+ assert_equals(win.getComputedStyle(div).height, expected_post);
+ }, `${value} computes to ${expected_post} after frame resize`);
+}
+
+test_invalidation_value('100vw', '200px', '400px');
+test_invalidation_value('100vi', '200px', '400px');
+test_invalidation_value('100vmax', '200px', '400px');
+test_invalidation_value('100svw', '200px', '400px');
+test_invalidation_value('100svi', '200px', '400px');
+test_invalidation_value('100svmax', '200px', '400px');
+test_invalidation_value('100lvw', '200px', '400px');
+test_invalidation_value('100lvi', '200px', '400px');
+test_invalidation_value('100lvmax', '200px', '400px');
+test_invalidation_value('100dvw', '200px', '400px');
+test_invalidation_value('100dvi', '200px', '400px');
+test_invalidation_value('100dvmax', '200px', '400px');
+
+test_invalidation_value('100vh', '100px', '300px');
+test_invalidation_value('100vb', '100px', '300px');
+test_invalidation_value('100vmin', '100px', '300px');
+test_invalidation_value('100svh', '100px', '300px');
+test_invalidation_value('100svb', '100px', '300px');
+test_invalidation_value('100svmin', '100px', '300px');
+test_invalidation_value('100lvh', '100px', '300px');
+test_invalidation_value('100lvb', '100px', '300px');
+test_invalidation_value('100lvmin', '100px', '300px');
+test_invalidation_value('100dvh', '100px', '300px');
+test_invalidation_value('100dvb', '100px', '300px');
+test_invalidation_value('100dvmin', '100px', '300px');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-keyframes.html b/testing/web-platform/tests/css/css-values/viewport-units-keyframes.html
new file mode 100644
index 0000000000..be43f22537
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-keyframes.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<title>Viewport units in @keyframes</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ iframe {
+ width: 200px;
+ height: 100px;
+ }
+</style>
+
+<iframe id=iframe></iframe>
+
+<script>
+
+const doc = iframe.contentDocument;
+const win = iframe.contentWindow;
+
+function test_interpolated_value(from, to, expected) {
+ test((t) => {
+ t.add_cleanup(() => { doc.body.innerHTML = ''; });
+ doc.body.innerHTML = `
+ <style>
+ @keyframes anim {
+ from { height: ${from}; }
+ to { height: ${to}}
+ }
+ div { animation: anim linear 10s -5s paused; }
+ </style>
+ <div></div>
+ `;
+ let div = doc.querySelector('div');
+ assert_equals(win.getComputedStyle(div).height, expected);
+ }, `Interpolation from ${from} to ${to} is ${expected} at 50%`);
+}
+
+// Flush the iframe styles before starting tests to avoid the animation in the
+// iframe starts before the iframe's document gets sized as expected.
+iframe.getBoundingClientRect();
+
+test_interpolated_value('0px', '100vw', '100px');
+test_interpolated_value('0px', '100vi', '100px');
+test_interpolated_value('0px', '100vmax', '100px');
+test_interpolated_value('0px', '100svw', '100px');
+test_interpolated_value('0px', '100svi', '100px');
+test_interpolated_value('0px', '100svmax', '100px');
+test_interpolated_value('0px', '100lvw', '100px');
+test_interpolated_value('0px', '100lvi', '100px');
+test_interpolated_value('0px', '100lvmax', '100px');
+test_interpolated_value('0px', '100dvw', '100px');
+test_interpolated_value('0px', '100dvi', '100px');
+test_interpolated_value('0px', '100dvmax', '100px');
+
+test_interpolated_value('0px', '100vh', '50px');
+test_interpolated_value('0px', '100vb', '50px');
+test_interpolated_value('0px', '100vmin', '50px');
+test_interpolated_value('0px', '100svh', '50px');
+test_interpolated_value('0px', '100svb', '50px');
+test_interpolated_value('0px', '100svmin', '50px');
+test_interpolated_value('0px', '100lvh', '50px');
+test_interpolated_value('0px', '100lvb', '50px');
+test_interpolated_value('0px', '100lvmin', '50px');
+test_interpolated_value('0px', '100dvh', '50px');
+test_interpolated_value('0px', '100dvb', '50px');
+test_interpolated_value('0px', '100dvmin', '50px');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-media-queries.html b/testing/web-platform/tests/css/css-values/viewport-units-media-queries.html
new file mode 100644
index 0000000000..3356179331
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-media-queries.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<title>Viewport units in @media</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ iframe {
+ width: 200px;
+ height: 100px;
+ }
+</style>
+
+<iframe id=iframe></iframe>
+
+<script>
+
+const doc = iframe.contentDocument;
+const win = iframe.contentWindow;
+
+function test_media_query(feature, result, description) {
+ test((t) => {
+ t.add_cleanup(() => { doc.body.innerHTML = ''; })
+ doc.body.innerHTML = `
+ <style>
+ body {
+ color: red;
+ }
+ @media (${feature}) {
+ body {
+ color: green;
+ }
+ }
+ </style>
+ `;
+ assert_equals(win.getComputedStyle(doc.body).color, result);
+ }, description);
+}
+
+function test_media_query_applies(feature) {
+ test_media_query(feature, 'rgb(0, 128, 0)', `@media(${feature}) applies`);
+}
+
+function test_media_query_does_not_apply(feature) {
+ test_media_query(feature, 'rgb(255, 0, 0)', `@media(${feature}) does not apply`);
+}
+
+test_media_query_applies('width:100vw');
+test_media_query_applies('width:100vi');
+test_media_query_applies('width:100vmax');
+test_media_query_applies('width:100svw');
+test_media_query_applies('width:100svi');
+test_media_query_applies('width:100svmax');
+test_media_query_applies('width:100lvw');
+test_media_query_applies('width:100lvi');
+test_media_query_applies('width:100lvmax');
+test_media_query_applies('width:100dvw');
+test_media_query_applies('width:100dvi');
+test_media_query_applies('width:100dvmax');
+
+test_media_query_applies('height:100vh');
+test_media_query_applies('height:100vb');
+test_media_query_applies('height:100vmin');
+test_media_query_applies('height:100svh');
+test_media_query_applies('height:100svb');
+test_media_query_applies('height:100svmin');
+test_media_query_applies('height:100lvh');
+test_media_query_applies('height:100lvb');
+test_media_query_applies('height:100lvmin');
+test_media_query_applies('height:100dvh');
+test_media_query_applies('height:100dvb');
+test_media_query_applies('height:100dvmin');
+
+test_media_query_does_not_apply('width:90vw');
+test_media_query_does_not_apply('height:90vh');
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-modify.html b/testing/web-platform/tests/css/css-values/viewport-units-modify.html
new file mode 100644
index 0000000000..8ce5d98712
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-modify.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Crash when going from non-viewport to viewport units</title>
+<link rel="help" href="https://crbug.com/1322613">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="elem" style="padding-left: 1vh">Test passes if there is no crash.</div>
+
+<script>
+
+test((t) => {
+ assert_not_equals(getComputedStyle(elem).paddingLeft, '0px');
+ elem.style.paddingLeft = '0';
+ assert_equals(getComputedStyle(elem).paddingLeft, '0px');
+ elem.style.paddingLeft = '1vh';
+ assert_not_equals(getComputedStyle(elem).paddingLeft, '0px');
+});
+
+</script>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-parsing.html b/testing/web-platform/tests/css/css-values/viewport-units-parsing.html
new file mode 100644
index 0000000000..4373b2a9f0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-parsing.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Values: parsing width with valid viewport units</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+const prefixes = ["", "s", "l", "d"];
+const suffixes = ["vw", "vh", "vi", "vb", "vmin", "vmax"];
+const units = [];
+
+for (const prefix of prefixes) {
+ for (const suffix of suffixes) {
+ units.push(prefix + suffix);
+ }
+}
+
+for (const unit of units) {
+ test_valid_value("width", "1" + unit);
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-writing-mode-font-size-ref.html b/testing/web-platform/tests/css/css-values/viewport-units-writing-mode-font-size-ref.html
new file mode 100644
index 0000000000..1e09173353
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-writing-mode-font-size-ref.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<title>CSS test reference</title>
+<meta charset="utf-8">
+<style>
+ .test {
+ width: 1em;
+ height: 1em;
+ background-color: green;
+ display: inline-block;
+ }
+ #t1 {
+ font-size: 1vh;
+ }
+ #t2 {
+ font-size: 1vw;
+ }
+ #t3 {
+ font-size: 1vh;
+ }
+ #t4 {
+ font-size: 1vw;
+ }
+</style>
+<div class="test" id="t1"></div>
+<div class="test" id="t2"></div>
+<div class="test" id="t3"></div>
+<div class="test" id="t4"></div>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-writing-mode-font-size.html b/testing/web-platform/tests/css/css-values/viewport-units-writing-mode-font-size.html
new file mode 100644
index 0000000000..fd1a4aaca5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-writing-mode-font-size.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<title>font-size depends on writing-mode</title>
+<meta charset="utf-8">
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="match" href="viewport-units-writing-mode-font-size-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<style>
+ .test {
+ width: 1em;
+ height: 1em;
+ background-color: green;
+ display: inline-block;
+ }
+ #t1 {
+ writing-mode: vertical-lr;
+ font-size: 1vi;
+ }
+ #t2 {
+ writing-mode: vertical-lr;
+ font-size: 1vb;
+ }
+ #t3 {
+ font-size: 1vi;
+ writing-mode: vertical-lr;
+ }
+ #t4 {
+ font-size: 1vb;
+ writing-mode: vertical-lr;
+ }
+</style>
+<div class="test" id="t1"></div>
+<div class="test" id="t2"></div>
+<div class="test" id="t3"></div>
+<div class="test" id="t4"></div>
diff --git a/testing/web-platform/tests/css/css-values/viewport-units-writing-mode.html b/testing/web-platform/tests/css/css-values/viewport-units-writing-mode.html
new file mode 100644
index 0000000000..ee851fd17c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-values/viewport-units-writing-mode.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<title>Viewport units are responsive to writing-mode changes</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ iframe {
+ width: 200px;
+ height: 100px;
+ }
+</style>
+
+<iframe id=iframe></iframe>
+
+<script>
+
+const doc = iframe.contentDocument;
+const win = iframe.contentWindow;
+
+function test_writing_mode(value, expected_pre, expected_post) {
+ test((t) => {
+ t.add_cleanup(() => { doc.body.innerHTML = ''; });
+ doc.body.innerHTML = `
+ <style>
+ div {
+ writing-mode: initial;
+ height: ${value};
+ }
+ .vertical {
+ writing-mode: vertical-rl;
+ }
+ </style>
+ <div></div>
+ `;
+ let div = doc.querySelector('div');
+ assert_equals(win.getComputedStyle(div).height, expected_pre);
+
+ // The writing-mode of the document element does not matter.
+ t.add_cleanup(() => { doc.documentElement.classList.remove('vertical'); })
+ doc.documentElement.classList.add('vertical');
+ assert_equals(win.getComputedStyle(div).height, expected_pre);
+
+ // The writing-mode of the target element is what matters.
+ div.classList.add('vertical');
+ assert_equals(win.getComputedStyle(div).height, expected_post);
+ }, `${value} computes to ${expected_post} with vertical writing-mode`);
+}
+
+test_writing_mode('100vi', '200px', '100px');
+test_writing_mode('100svi', '200px', '100px');
+test_writing_mode('100lvi', '200px', '100px');
+test_writing_mode('100dvi', '200px', '100px');
+
+test_writing_mode('100vb', '100px', '200px');
+test_writing_mode('100svb', '100px', '200px');
+test_writing_mode('100lvb', '100px', '200px');
+test_writing_mode('100dvb', '100px', '200px');
+
+</script>