tag

#razor

51 items (51 fixes)

fixes
26.07.08e
"@ref on a bare private field silently never assigns"

@ref on a private field compiles with only a CS0649 warning: the ref stays null at runtime. Bind to a property instead.

26.08.05
"#if DEBUG in a .razor file is always false: dev panels leak into release"

A #if DEBUG guard inside a .razor component is always false in every configuration, so it strips nothing, and the razor source plus any sibling .scss ship into the uploaded package as readable text regardless. Build anything that must be absent from a release as a plain .cs class.

26.07.22
"A code-behind Panel has no Style.Rotate shortcut: rotate it with a PanelTransform"

A pure C# Panel subclass has no settable Style.Rotate shortcut reachable from code the way razor markup can write transform:rotate(Xdeg). Rotate it by building a PanelTransform, calling AddRotation, and assigning it to Style.Transform each frame the angle changes.

26.08.05
"A flex: 1 spacer in a clipping column hides every control after it"

A flex: 1 spacer takes all remaining height in a column, so every sibling after it starts at the container's bottom edge. Under overflow: hidden those trailing controls are laid out but never drawn: hover and onclick stay intact while zero pixels reach the screen. Put a spacer between two blocks that both fit, or bottom-anchor a group with margin-top: auto.

26.07.22
"A green offline dotnet build misses s&box whitelist violations"

Compiling an s&box game assembly outside the editor needs the exact csproj shape the editor generates, and even a perfectly green offline build cannot surface whitelist violations. The SB1000 analyzer runs only in the editor compile pass, so code can build with 0 errors and 0 warnings offline and still be rejected in-editor. Build the editor-generated Code/<project>.csproj directly and confirm against the editor compile_status, never the offline build alone.

26.07.22
"A literal glued to the front of a Razor expression parses as an email address"

In a .razor file, `word@Expr.Member` (e.g. `P@Score.Value`) is parsed as a literal string, not an expression. Razor's email-address heuristic sees the `foo@bar.baz` shape and treats the whole thing as text. The element renders the raw source, with no compile error and no warning. Put the literal inside the expression instead: `@($"P{Score.Value}")`.

26.07.08e
"A loose PNG in razor CSS renders in the editor but goes blank in the published build"

A razor background-image referencing a loose PNG/JPG renders in-editor (loose Assets are readable off the mounted filesystem) but goes blank in the published package, because loose non-compiled images are not auto-shipped. Add the disk glob to the sbproj Resources list; the wildcard matches the loose disk path, not the normalized asset path.

26.07.22
"A panel's width and height are the outer size (border-box by default)"

In s&box razor UI the declared width/height of a panel is the OUTER number: padding and borders sit inside it, not added on top. The default already behaves like box-sizing: border-box, with no such declaration anywhere. Author every width/height as the outer number the mockup shows; adding padding/border by hand under-sizes every box by exactly its own padding.

26.07.22
"A percent-sized absolute fill floods the panel when its track has no position"

An absolutely positioned child with a percent size resolves against the nearest ancestor that is a positioning context, not against the track you can see. A track div does not become a positioning context by carrying flex, padding, a background, or a fixed size. It needs an explicit position declaration. Without one, height: 100% resolves against the panel root, so a stat-bar fill sized width N percent by height 100 percent floods the whole panel and buries the cards under it. Set position: relative on the track, then sweep every sibling with the same pattern, because small absolute children hide the same defect by landing in the wrong corner instead of flooding.

26.07.22
"A ScreenPanel lays out against a height-fixed logical canvas, not a fixed 1920x1080"

A ScreenPanel lays out against a logical canvas that is fixed in height at 1080 and takes its width from the window aspect ratio. At a 1920x1080 window the canvas measures 2060.7 x 1080, not 1920 x 1080. Vertical and left-anchored values from a 1920-wide mockup transfer 1:1, but anything hard-centred with arithmetic against an assumed 1920 width sits off-centre. Centre with flex, never with math.

26.08.05
"A scroll container steals press-and-drag from every control inside it"

A Panel with overflow: scroll and real overflow content answers WantsDrag = true, and FindDragTarget walks up from the pointer to the first ancestor that claims the drag. That ancestor steals every press-and-drag from any slider, scrub bar, or knob inside it. Set CanDragScroll = false on the scroll container in OnTreeBuilt.

26.07.22
"A text line box is the taller of the declared line-height and the font's natural box"

A text element's line box measures max(declared line-height, the font's own natural box), so a column of rows built to a browser mockup's arithmetic runs long and overflows its fixed parent. Padding, borders, margins and gaps all measure exactly as declared: only the line box inflates. Size rows off the font size, not off an assumed 1.5×, and verify on a scale-1 capture.

26.07.15a
"A uniform font-size declaration still triggers glyph corruption"

SUPERSEDED: the font-size-declaration theory below was owner-settled (26.07.22) to be a CAPTURE-PATH artifact, not a live-render bug, and the mechanism was later traced to the root panel's fractional scale. Never strip font-size or letter-spacing from a shipping stylesheet to 'fix' captures. See camera-screenshot-cannot-verify-fonts.

26.07.08e
"Absolutely-positioned flex column with auto height silently drops trailing children"

Trailing children of a tall absolutely-positioned flex column silently vanish (no overflow, no compression) because Yoga's auto-height under-measures the content. Fix: give the column an explicit height.

26.08.05
"An absolute child of an unpositioned panel escapes to the screen, not the panel"

An absolutely positioned child clips to the nearest ancestor that is a positioning context, not to its visual parent. A frame with flex, a fixed size, and a border radius but no position declaration is not a positioning context, so the absolute child skips past it and renders full-bleed against the screen root. A sibling screen using the same pattern renders correctly only because its own box already was the root, which makes the pattern look safe to copy. For one rectangle, drop the absolute child and paint the texture on the frame's own background.

26.07.15a
"An MCP camera_screenshot cannot verify font faces or text legibility"

Glyph-block corruption in an MCP camera_screenshot is a capture-path artifact, not a live-render bug. The same UI renders text perfectly on the real screen. You cannot screenshot your way out of it: the requested width/height does not change the UI render scale, and sub-native requests crop the top-left. Verify geometry from a capture, never text fidelity; font-face and legibility are owner-eyeball checks.

26.07.15
"An undefined scss variable silently kills the whole panel -- no compile gate catches it"

Referencing an scss variable a sheet never defines passes both dotnet build and the in-editor compile_status clean, but at runtime the style parser logs a 'malformed rule' warning and the panel using that sheet can stop rendering entirely. Variables don't cross sheets, so copying a rule between sheets silently drops its variables.

26.07.15a
"Assembly.cs global usings as project bootstrap"

global using Sandbox + your razor namespace in Assembly.cs: without it, panels and game types don't resolve across the assembly.

26.07.15a
"border-style: solid is a parse error that kills the whole stylesheet"

border-style: solid is a parse error in s&box scss. The invalid property aborts the whole stylesheet, collapsing the panel to zero size -- invisible, not just unbordered.

26.07.22
"box-shadow: inset paints outside the element in Razor panels"

The inset keyword on box-shadow is effectively ignored in s&box Razor panels: an inner vignette renders as an outer halo, and a full-screen inset vignette renders nothing at all. Build inner glows and vignettes from linear-gradient bands instead.

26.07.15a
"BuildHash() overrides only compile on PanelComponent, not on a plain Component"

protected override int BuildHash() is a PanelComponent member; a logic-only Component has no such method, so the override fails headless with CS0115. Easy to hit when you split a UI feature into a logic Component beside its PanelComponent view and copy the 'keep the tree stable' BuildHash idiom onto the logic component too.

26.07.08e
"Building a draggable slider with click-to-jump and drag-to-scrub"

No native drag helper exists for PanelComponent sliders. Use the engine's SliderControl pattern: MousePanelEvent.LocalPosition over track width, with pointer-events routing.

26.07.08e
"Building an s&box HUD"

One ScreenPanel host, static UIState for modals, self-closing panels, toast stack: BuildHash every flag the markup reads.

26.07.15a
"Child-combinator universal selector (`.parent > *`) never matches in s&box SCSS"

A child-combinator rule targeting the universal selector (`.parent > *`) is silently dead in s&box razor SCSS: no error, no warning, the rule simply never applies.

26.07.15a
"CSS @keyframes and animation shorthand work in razor SCSS"

CSS @keyframes plus the animation: shorthand are supported in s&box razor SCSS, so a spinner or looping effect is pure CSS -- do not drive it from a per-frame BuildHash re-render.

26.07.15a
"Defer a synchronous blocking call a few frames so the loading overlay actually paints"

Showing a loading overlay and running a synchronous main-thread job in the same handler never paints the overlay -- the blocking work runs before the render pass. Show the overlay, count down a couple of frames, then run the blocker in OnUpdate.

26.07.08e
"Editing .razor safely (shell/emoji mojibake)"

Razor HUD emoji and dashes die under Get-Content/Set-Content: edit with byte-safe UTF-8 APIs or a real editor.

26.07.08e
"Glyph corruption (text renders as solid blocks) is also text-count dependent"

SUPERSEDED: the text-run-count theory below was owner-settled (26.07.22) to be a CAPTURE-PATH artifact, not a live-render bug, and the mechanism was later traced to the root panel's fractional scale. Do not trim text runs to 'fix' glyph blocks in a capture.

26.07.08e
"Headless dotnet build misses Razor compile errors"

dotnet build reports 0 errors on .razor files the in-editor compiler rejects: the headless build doesn't surface the Razor errors the live editor's Roslyn compiler flags.

26.08.05
"Inside one panel tree, z-index paints the popup but does not order the click"

A dropdown paints cleanly over the block below it, and that block still eats every press. Paint order and hit order come from two different sums: render depth accumulates z-index down the tree, but hit-testing ranks siblings by SiblingIndex + ZIndex within each parent. An absolute menu that overhangs a later sibling looks perfect and is unclickable. Fix the ancestors, not the popup.

26.07.08e
"My s&box UI won't update / is frozen"

BuildHash() is the only re-render trigger: hash everything the markup reads, including collection contents and flags.

26.07.08e
"New .razor.scss files are not applied until the editor restarts"

A newly created .razor.scss file is not picked up by a running editor session: the panel component works but is unstyled until the next restart.

26.07.08e
"PanelComponent uses OnTreeBuilt, not OnAfterTreeRender"

OnAfterTreeRender(bool) is a Panel hook: on a PanelComponent it fails with CS0115; use parameterless OnTreeBuilt() or OnTreeFirstBuilt().

26.07.08e
"Razor panel mounted before a sync call never paints: budget frames, not ticks"

A loading screen mounted right before a synchronous multi-second call never paints: one consumed tick isn't enough; gate the block on a frame counter (~6 frames) so the Razor pipeline finishes mount → style → layout → paint.

26.07.08e
"Razor RenderFragment flex rows with gap collapse on top of each other"

Thin flex rows with a gap inside a Razor RenderFragment expression under-measure their height and pile on top of each other. The same markup renders fine in the component's main root.

26.07.18
"Razor tag resolution ignores global usings"

Razor component tag resolution does not consult global using directives: a library component renders as an inert HTML element while its class resolves fine in code-behind.

26.07.15a
"Render a player's Steam avatar with the avatar: texture-URL scheme"

s&box loads Steam avatars through an avatar:<steamid64> texture-URL scheme usable from both SCSS background-image and C# Texture.Load. It returns a transparent placeholder immediately and swaps in the real avatar with no panel re-render.

26.07.08e
"Runtime textures for UI panels must be assigned from C#"

SCSS background-image only resolves asset paths. Runtime Texture objects must be assigned via Panel.Style.BackgroundImage in OnTreeBuilt.

26.07.08e
"RZ1010 error from nested @{ } inside a Razor code block"

Nesting @{ } inside an already-open Razor code block (like @if or @for) causes RZ1010: you're already in C#, so drop the @.

26.07.08e
"ScenePanel Camera is read-only: configure it in place for 3D previews"

ScenePanel's Camera property is GET-ONLY. Assigning a new SceneCamera fails with CS0200. Configure the existing camera in place and build the preview world manually.

26.07.22
"ScreenPanel.ZIndex defaults to 100, and tied roots have no paint order"

ScreenPanel.ZIndex defaults to 100 (not 0), so any ScreenPanel that never sets a tier collides with the tier most projects author their modals at, and two roots with equal ZIndex have no defined paint order at all. Cross-root compositing is a stable OrderBy over an unordered HashSet, so tied roots keep an enumeration order that matches creation on a fresh boot but re-rolls on any enable/disable interleave or editor hotload. A full-screen surface can paint a perfectly healthy tree and still be invisible under a tied root.

26.07.22
"ScreenPanel.ZIndex orders paint only: pointer input falls through"

ScreenPanel.ZIndex orders paint only: pointer input is NOT routed by cross-root stacking, so a lower-ZIndex root keeps swallowing clicks even when a higher-ZIndex modal draws over it.

26.07.08e
"Structural Razor edit hotload exception silently deregisters project tools"

A structural .razor change can throw a hotload exception that deregisters the project's entire toolset while compile_status still reports Success. Restart the editor to recover.

26.07.08e
"TextEntry is the house control, not HTML input"

Use TextEntry with onsubmit and OnTextEdited: standard Blazor input bindings compile but are not how the engine UI works.

26.07.15a
"TextEntry.OnTextEdited needs an explicit-type block lambda"

An untyped or expression-bodied lambda on TextEntry.OnTextEdited fails with CS8917 or CS0029. Use an explicit param type plus a block body.

26.07.08e
"The Razor @namespace trap"

Razor classes get a RootNamespace/folder-derived namespace: declare @namespace and global using or C# can't find your panels.

26.07.08e
"Three ways Razor text is in the DOM but invisible on screen"

s&box Razor panels have three distinct 'text is there but not on screen' failure modes (long-line clipping, narrow-segment overflow, and inline expression resolution), each with a different structural fix.

26.07.22
"transition-delay, :intro and :outro parse cleanly in razor-scss"

transition-delay, :intro and :outro all parse in the engine's razor-scss pipeline, tested isolated on engine build 26.07.22. An earlier caution that treated these selectors as unsupported can relax. A novel selector is worth one isolated test before you write it off, because an unparsed selector aborts the whole stylesheet to a 0x0 render.

26.07.22
"Undefined SCSS variable silently kills panels at runtime"

An undefined SCSS variable in a .razor.scss fails at runtime with only a console warning (no compile error, no toast) and the affected panels can render fully invisible. A trailing // comment on a value line fails the same way.

26.07.08e
"Whitespace next to a Razor tag or expression boundary collapses to nothing"

Literal spaces adjacent to a tag or @-expression boundary vanish in Razor markup: use a single interpolated string or CSS margin instead.

26.07.22
"Writing focus from onmouseover rebuilds the panel and swallows the click"

A button that never responds, with a clean console and a correct onclick handler, can be a BuildHash rebuild eating the click. If you write a focus-cursor field from onmouseover and that field participates in the panel's BuildHash, the mouse arriving over a row rebuilds the panel tree on the spot. The rebuild destroys and recreates the element under the cursor, and a press and release that straddles the rebuild is swallowed by the engine, so no onclick fires. Focus is a keyboard and gamepad concept, so never write it from a hover handler. Give the mouse its own affordance from CSS :hover, which needs no rebuild, and keep the keyboard focus index as a separate field if the panel needs both.

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord