A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

Fix handle CTA overflowing and clipping the Start button on mobile

The landing CTA row is a flexbox holding the input field (flex: 1) and the
Start button. Flex items default to min-width: auto, which forbids shrinking
below the content's intrinsic width — and the <input> carries a large
intrinsic floor (~241px). On narrow phones the field couldn't shrink, so the
row grew past its container and pushed Start off the right edge (reproduced at
<=320px CSS px, where it overflowed by 44px and rendered as "Star...").

Add min-width: 0 to both flex children so the field — and the input nested
inside it — can collapse to fit the available width. Guarded by a source-level
regression test, matching the _index.phase.test.ts pattern (the runner is
pinned to jsdom for the WP block suites, so rendering through astro/container
isn't viable).

+56
+51
src/pages/_index.handlestart.test.ts
··· 1 + /** 2 + * Regression guard for the landing-page handle CTA overflowing on narrow viewports. 3 + * 4 + * `.handlestart__row` is a flexbox row holding the input field (`flex: 1`) and the "Start" 5 + * button. A flex item's default `min-width: auto` refuses to shrink below its content's 6 + * intrinsic width — and the `<input>` carries a sizeable intrinsic floor. Without an explicit 7 + * `min-width: 0` on the field (and the input nested inside it), the field can't shrink on a 8 + * phone-width screen, so the row grows past the container and clips the "Start" button off the 9 + * right edge (reported 2026-06-09, reproduced at <=320px CSS px). 10 + * 11 + * Rendering the page through astro/container isn't viable here (the runner is pinned to jsdom 12 + * for the WordPress block suites), so — as with _index.phase.test.ts — these asserts pin the 13 + * fix at the source level. 14 + */ 15 + import { readFileSync } from 'node:fs'; 16 + import { fileURLToPath } from 'node:url'; 17 + import { describe, expect, it } from 'vitest'; 18 + 19 + const read = ( rel: string ) => 20 + readFileSync( fileURLToPath( new URL( rel, import.meta.url ) ), 'utf8' ); 21 + 22 + /** Pull the body of a CSS rule (between its `{` and the matching `}`) for the given selector. */ 23 + const ruleBody = ( css: string, selector: string ): string => { 24 + const start = css.indexOf( selector ); 25 + if ( start === -1 ) { 26 + return ''; 27 + } 28 + const open = css.indexOf( '{', start ); 29 + const close = css.indexOf( '}', open ); 30 + return css.slice( open + 1, close ); 31 + }; 32 + 33 + describe( 'landing page handle CTA shrinks on narrow viewports', () => { 34 + const style = read( './index.astro' ).match( /<style>([\s\S]*?)<\/style>/ )?.[ 1 ] ?? ''; 35 + 36 + it( 'lets the field shrink below the input intrinsic width (min-width: 0)', () => { 37 + const body = ruleBody( style, '.handlestart__field)' ); 38 + expect( body, 'expected a .handlestart__field rule in the landing styles' ).not.toBe( '' ); 39 + expect( body, '.handlestart__field must set min-width: 0 so it can shrink in the flex row' ).toMatch( 40 + /min-width:\s*0\b/ 41 + ); 42 + } ); 43 + 44 + it( 'lets the input itself shrink inside the field (min-width: 0)', () => { 45 + const body = ruleBody( style, '.handlestart__input)' ); 46 + expect( body, 'expected a .handlestart__input rule in the landing styles' ).not.toBe( '' ); 47 + expect( body, '.handlestart__input must set min-width: 0 so the field can collapse around it' ).toMatch( 48 + /min-width:\s*0\b/ 49 + ); 50 + } ); 51 + } );
+5
src/pages/index.astro
··· 444 444 .hero :global(.handlestart__row) { display: flex; gap: 0.5rem; } 445 445 .hero :global(.handlestart__field) { 446 446 flex: 1; 447 + /* Allow the field to shrink below the input's intrinsic width so the row never 448 + overflows and clips the Start button on narrow viewports. */ 449 + min-width: 0; 447 450 display: flex; 448 451 align-items: center; 449 452 gap: 0.15rem; ··· 457 460 .hero :global(.handlestart__at) { color: var(--sky-soft); } 458 461 .hero :global(.handlestart__input) { 459 462 flex: 1; 463 + /* Pair with the field's min-width: 0 — let the input collapse so the field can too. */ 464 + min-width: 0; 460 465 border: none; 461 466 background: transparent; 462 467 color: var(--sky-ink);