Skip to content

Support single-value scale() and translate() in CSS transform - #39717

Open
johnkaram02 wants to merge 1 commit into
dotnet:mainfrom
johnkaram02:fix/css-transform-single-value
Open

johnkaram02 wants to merge 1 commit into
dotnet:mainfrom
johnkaram02:fix/css-transform-single-value

Conversation

@johnkaram02

Copy link
Copy Markdown

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description of Change

transform: scale(2); and transform: translate(10); threw IndexOutOfRangeException in VisualElement.OnTransformChanged, because the handler always read a second comma-separated value.

CSS defines scale(s) as scale(s, s) and translate(tx) as translate(tx, 0). This change applies those defaults when only one value is present. The two-value forms keep their current behavior.

Tests: adds TransformScaleWithSingleValueScalesBothAxes, TransformTranslateWithSingleValueTranslatesXOnly and TransformScaleAndTranslateWithTwoValues to StyleSheets/StyleTests.cs. The first two fail without the change and pass with it. I ran Controls.Core.UnitTests on Linux (net10.0): 5868 passed, 30 skipped, 0 failed. I did not test on a device.

Issues Fixed

Fixes #

Setting the CSS `transform` property to `scale(2)` or `translate(10)`
threw an IndexOutOfRangeException from VisualElement.OnTransformChanged,
because the handler always read a second comma-separated value.

In CSS, `scale(s)` is the same as `scale(s, s)` and `translate(tx)` is
the same as `translate(tx, 0)`. Apply those defaults when only one
value is present.
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 39717

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 39717"

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label Oct 28, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Hey there @@johnkaram02! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Hey there @johnkaram02! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@kubaflo

This comment has been minimized.

@kubaflo

This comment has been minimized.

@azure-pipelines

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Oct 28, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expert Review — 0 findings

Reviewed commit d0a1067.

@MauiBot

MauiBot commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator

PR Test Gate

@johnkaram02 — existing-test verification for commit d0a10674.

Result PASSED Platform Android Commit d0a10674


🧪 Gate analysis — click to expand

✅ Passed. The selected verification satisfied the gate's passing conditions. Unmatched, skipped, or inconclusive groups are not passing evidence.

🧪 Unit tests
Test group Without fix With fix
StyleTests ✅ Failed as expected (120s) ✅ Passed (71s)
Execution log excerpts

Without fix StyleTests

     at Microsoft.Maui.Controls.VisualElement.OnTransformChanged(BindableObject bindable, Object oldValue, Object newValue) in /_/src/Controls/src/Core/VisualElement/VisualElement.cs:line 238
   at Microsoft.Maui.Controls.BindableObject.OnBindablePropertySet(BindableProperty property, Object original, Object value, Boolean didChange, Boolean willFirePropertyChanged) in /_/src/Controls/src/Core/BindableObject.cs:line 721
   at Microsoft.Maui.Controls.Element.OnBindablePropertySet(BindableProperty property, Object original, Object value, Boolean changed, Boolean willFirePropertyChanged) in /_/src/Controls/src/Core/Element/Element.cs:line 713
   at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent) in /_/src/Controls/src/Core/BindableObject.cs:line 708
   at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity) in /_/src/Controls/src/Core/BindableObject.cs:line 625
   at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value, SetterSpecificity specificity) in /_/src/Controls/src/Core/BindableObject.cs:line 559
   at Microsoft.Maui.Controls.StyleSheets.Style.Apply(VisualElement styleable, SelectorSpecificity selectorSpecificity, Boolean inheriting) in /_/src/Controls/src/Core/StyleSheets/Style.cs:line 81
   at Microsoft.Maui.Controls.StyleSheets.UnitTests.StyleTests.TransformTranslateWithSingleValueTranslatesXOnly() in /_/src/Controls/tests/Core.UnitTests/StyleSheets/StyleTests.cs:line 193
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
     at Microsoft.Maui.Controls.VisualElement.OnTransfor

With fix StyleTests

itInheritedStyleForTemplatedElementIsAppliedCorrectlyForContentView [1 ms]
  Passed UnapplyingStyleDefaultToImplicit2 [< 1 ms]
  Passed ImplicitStylesAreAppliedOnSettingRD [1 ms]
  Passed AddImplicitStyleToResourceDictionary [6 ms]
  Passed CreatingStyledElementsOffMainThreadShouldNotCrash [2 s]
  Passed MatchTargetTypeDoesntLogWarningMessage [1 ms]
  Passed TestTriggersAndBehaviors [3 ms]
  Passed ImplicitStylesAreAppliedToDerivedIfSpecified [1 ms]
  Passed StyleDontHoldStrongReferences [50 ms]
  Passed MismatchTargetTypeLogsWarningMessage2 [25 ms]
  Passed MismatchTargetTypeLogsWarningMessage1 [2 ms]
  Passed ClearValueShouldntUnapplyStyles [1 ms]
  Passed MultipleStyleClassAreApplied [1 ms]
[xUnit.net 00:00:06.21]   Finished:    Microsoft.Maui.Controls.Core.UnitTests
  Passed ImplicitStylesNotAppliedToDerivedTypesByDefault [1 ms]
  Passed UnapplyingStyleDefaultToImplicit5 [1 ms]
  Passed ImplicitStylesAppliedByDefaultIfAStyleExists [1 ms]
  Passed ReplacingResourcesDoesNotOverrideManuallySetProperties [2 ms]
  Passed MultipleStylesCanShareTheSameClassName [1 ms]
  Passed ClassStylesAreApplied [1 ms]
Test Run Successful.
Total tests: 53
     Passed: 53
 Total time: 7.1750 Seconds

PR head: d0a10674.

Without-fix baseline: b20099cf.

@MauiBot MauiBot added s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) and removed s/agent-review-in-progress AI review is currently running for this PR labels Oct 28, 2026

This branch was previously deployed

1 inactive deployment
copilot-pat-pool — d0a10674 Deployed Oct 28, 2026 by johnkaram02 via conclusion #2548
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community ✨ Community Contribution s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants