Skip to content

Constrain blog image heights on mobile viewports#2548

Closed
google-labs-jules[bot] wants to merge 8 commits into
mainfrom
responsive-blog-images-2506384352431685448
Closed

Constrain blog image heights on mobile viewports#2548
google-labs-jules[bot] wants to merge 8 commits into
mainfrom
responsive-blog-images-2506384352431685448

Conversation

@google-labs-jules

Copy link
Copy Markdown
Contributor

This change fixes the issue where oversized images in blog posts dominated the mobile viewport. All article images (Hero, Markdown, and Mermaid diagrams) are now constrained to a maximum height of 50vh on mobile devices. Desktop layouts remain unaffected and continue to use their designated height limits (e.g., 96 units/384px for hero images).

Key changes:

  • Introduced a new img-constrained utility in src/index.css to centralize the 50vh mobile limit.
  • Applied this utility to EditorialHero.tsx, ensuring the inner ProductImageFrame respects the limit and correctly resets on larger screens.
  • Applied this utility to standard images and Mermaid diagrams in MarkdownRenderer.tsx, using responsive classes to maintain desktop behavior (md:max-h-none for standard images and md:max-h-96 for Mermaid).
  • Verified the fix with automated tests and visual verification scripts.

Fixes #2533


PR created automatically by Jules for task 2506384352431685448 started by @arii

- Added `img-constrained` utility in `index.css` for `max-height: 50vh`.
- Updated `EditorialHero` to apply height constraints on mobile while preserving desktop sizing.
- Updated `MarkdownRenderer` to apply constraints to article images and Mermaid diagrams.
- Verified mobile (375px) and desktop (1280px) layouts via Playwright.
- Ensured no regressions and compliance with UI anti-pattern audit.
@google-labs-jules

Copy link
Copy Markdown
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

🚀 Impact Analysis Details (Last updated: Jun 18, 2026, 4:22 PM PST)

Impact Analysis Complete

Deployment Review

Summary

Impact Level: HIGH

📝 Changed Files (5)
  • src/components/editorial/EditorialHero.tsx
  • src/components/ui/MarkdownRenderer.tsx
  • src/index.css
  • src/layouts/Box.tsx
  • src/layouts/layout-maps.ts

Routes Reviewed

/ (Visual Diff: 0.04%)

Severity: LOW
Review Required: No

DOM Changes:
None

Artifacts:

  • Before screenshot: artifacts/visual-review/home/before.png
  • After screenshot: artifacts/visual-review/home/after.png
  • Visual diff: artifacts/visual-review/home/diff.png
  • Before (cropped): artifacts/visual-review/home/cropped/before.png
  • After (cropped): artifacts/visual-review/home/cropped/after.png
  • Visual diff (cropped): artifacts/visual-review/home/cropped/diff.png
  • DOM diff: artifacts/dom-review/home/diff.txt
/about (Visual Diff: 0.02%)

Severity: LOW
Review Required: No

DOM Changes:
None

Artifacts:

  • Before screenshot: artifacts/visual-review/about/before.png
  • After screenshot: artifacts/visual-review/about/after.png
  • Visual diff: artifacts/visual-review/about/diff.png
  • Before (cropped): artifacts/visual-review/about/cropped/before.png
  • After (cropped): artifacts/visual-review/about/cropped/after.png
  • Visual diff (cropped): artifacts/visual-review/about/cropped/diff.png
  • DOM diff: artifacts/dom-review/about/diff.txt
/blog (Visual Diff: 0.00%)

Severity: LOW
Review Required: No

DOM Changes:
None

Artifacts:

  • Before screenshot: artifacts/visual-review/blog/before.png
  • After screenshot: artifacts/visual-review/blog/after.png
  • Visual diff: artifacts/visual-review/blog/diff.png
  • Before (cropped): artifacts/visual-review/blog/cropped/before.png
  • After (cropped): artifacts/visual-review/blog/cropped/after.png
  • Visual diff (cropped): artifacts/visual-review/blog/cropped/diff.png
  • DOM diff: artifacts/dom-review/blog/diff.txt
/merch (Visual Diff: 0.01%)

Severity: LOW
Review Required: No

DOM Changes:
None

Artifacts:

  • Before screenshot: artifacts/visual-review/merch/before.png
  • After screenshot: artifacts/visual-review/merch/after.png
  • Visual diff: artifacts/visual-review/merch/diff.png
  • Before (cropped): artifacts/visual-review/merch/cropped/before.png
  • After (cropped): artifacts/visual-review/merch/cropped/after.png
  • Visual diff (cropped): artifacts/visual-review/merch/cropped/diff.png
  • DOM diff: artifacts/dom-review/merch/diff.txt
/research (Visual Diff: 0.02%)

Severity: LOW
Review Required: No

DOM Changes:
None

Artifacts:

  • Before screenshot: artifacts/visual-review/research/before.png
  • After screenshot: artifacts/visual-review/research/after.png
  • Visual diff: artifacts/visual-review/research/diff.png
  • Before (cropped): artifacts/visual-review/research/cropped/before.png
  • After (cropped): artifacts/visual-review/research/cropped/after.png
  • Visual diff (cropped): artifacts/visual-review/research/cropped/diff.png
  • DOM diff: artifacts/dom-review/research/diff.txt

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

🐙 GitHub Models Code Review

Powered by GitHub Models

Reviewing: PR #2548

Code Review Feedback

HIGH SEVERITY REVIEW

1. Type Contradiction in Box Component's maxHeight Prop

Evidence:

  • In src/layouts/Box.tsx, the maxHeight prop is typed as:
    maxHeight?: ResponsiveProp<"none" | "viewport-half" | "full" | "screen" | "auto" | "min" | "fit" | number | string>
  • In EditorialHero.tsx and MarkdownRenderer.tsx, maxHeight is passed as:
    maxHeight={{ base: "viewport-half", lg: 96 }}
    and
    maxHeight={{ base: "50vh", lg: 96 }}
  • In the Box implementation, the responsive class generator for maxHeight:
    getResponsiveClasses(maxHeight, "max-h-", (v) => {
      if (v === "viewport-half") return "[50vh]";
      if (v === "none") return "[none]";
      const token = SPACING_MAP[v as keyof typeof SPACING_MAP];
      if (token) return token;
      return resolveJIT(v, "");
    }),
  • In MarkdownRenderer.tsx, the value passed is "50vh" (string), not "viewport-half".

Blocking Issue:

  • The Box component expects "viewport-half" as a token, but in MarkdownRenderer.tsx, the value "50vh" is passed directly:
    maxHeight={{ base: "50vh", lg: 96 }}
  • This means the responsive class generator will not match "viewport-half", nor will it find "50vh" in SPACING_MAP, so it falls through to resolveJIT("50vh", ""), which may not produce the intended CSS class (likely max-h-[50vh]).
  • This is a contradiction between the intended token usage and the actual value passed. If the utility classes are not generated for arbitrary values (e.g., Tailwind JIT), this will break the layout and the constraint will not be applied.

Action Required:

  • Fix the value passed to maxHeight in MarkdownRenderer.tsx: It should be "viewport-half", not "50vh", to match the token system and ensure the correct class is generated.
    • Change:
      maxHeight={{ base: "50vh", lg: 96 }}
      to:
      maxHeight={{ base: "viewport-half", lg: 96 }}
  • Verify that all usages of maxHeight use the token "viewport-half" and not the raw "50vh" string.

2. Potential Missing Type for maxHeight Responsive Prop

Evidence:

  • The maxHeight prop is typed as:
    ResponsiveProp<"none" | "viewport-half" | "full" | "screen" | "auto" | "min" | "fit" | number | string>
  • The responsive prop system expects keys like base, lg, etc., but if a value is passed that is not in the union, it will fall through to string, which is not type-safe.

Blocking Issue:

  • If "50vh" is passed, TypeScript will not catch this as an error, but the class generator will not handle it as intended. This is a type safety issue that can lead to runtime bugs.

Action Required:

  • Restrict the union type for maxHeight to only allow tokens defined in SPACING_MAP and not arbitrary strings.
  • Audit all usages to ensure only valid tokens are passed.

Summary of Blocking Issues:

  • Passing "50vh" instead of "viewport-half" to maxHeight in MarkdownRenderer.tsx will break the intended layout constraint and is a contradiction between the token system and actual usage.
  • The type for maxHeight is too permissive, allowing arbitrary strings that may not be handled correctly.

Final Verdict:

[VERDICT: FAIL]


Generated by github-models-code-review

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployment Details (Last updated: Jun 18, 2026, 6:37 PM PST)

🚀 Pushed to gh-pages; publish in progress

- Introduced `.img-constrained` utility in `src/index.css` (using standard `@layer utilities` syntax).
- Applied height constraints to `EditorialHero` on mobile while preserving desktop sizing.
- Applied height constraints and `object-contain` to markdown-embedded images and Mermaid diagrams.
- Verified fix on mobile (375px) and desktop (1280px) viewports via Playwright on production builds.
- Ensured compliance with UI anti-pattern audits and automated code reviews.
- Added `viewport-half` spacing token (50vh) to `index.css` theme.
- Updated `EditorialHero` to apply `maxHeight={{ base: "viewport-half", lg: 96 }}`.
- Updated `MarkdownRenderer` to apply `viewport-half` to images and Mermaid diagrams.
- Verified fix across mobile (375px), tablet (768px), and desktop (1280px) viewports.
- Ensured compliance with UI audits and addressed code review feedback regarding CSS specificity and arbitrary values.
- Added `viewport-half` spacing token (50vh) to `index.css` theme.
- Updated `SPACING_MAP` and `Box` component types to support `none` and `viewport-half`.
- Applied `maxHeight={{ base: "viewport-half", lg: 96 }}` to `EditorialHero`.
- Applied `maxHeight={{ base: "viewport-half", md: "none" }}` to blog images and diagrams.
- Verified fix across mobile (375px) and desktop viewports on production builds.
- Ensured type safety and addressed automated review feedback regarding CSS specificity.
Summary of changes:
- Introduced a new design token `viewport-half` (mapped to `50vh`) in `src/index.css`.
- Updated `src/layouts/layout-maps.ts` to include `viewport-half` and `none` in the `SPACING_MAP`.
- Enhanced `src/layouts/Box.tsx` by adding `viewport-half` and `none` to the `maxHeight` prop type union and updating the resolution logic to correctly handle these tokens across breakpoints.
- Applied `maxHeight={{ base: "viewport-half", lg: 96 }}` to `EditorialHero.tsx` to limit hero image size on mobile while preserving desktop design.
- Applied `maxHeight={{ base: "viewport-half", md: "none" }}` and `object-contain` to images in `MarkdownRenderer.tsx`, ensuring they fit the viewport without being cropped awkwardly.
- Applied consistent constraints to Mermaid diagrams in blog posts.

I encountered several rounds of feedback from automated reviewers regarding CSS specificity and type safety. I resolved these by moving away from custom utility classes and inline styles toward a first-class design token integrated into the project's primitive layout system. Verified the final solution across mobile (375px), tablet (768px), and desktop (1280px) viewports using production builds and Playwright scripts.
Implemented a responsive height constraint for blog post images to prevent them from dominating mobile viewports.

Key changes:
- Defined a `viewport-half` design token (50vh) in the theme.
- Updated the `Box` layout primitive to support `maxHeight` tokens including `viewport-half` and `none`.
- Applied `maxHeight={{ base: "viewport-half", lg: 96 }}` to `EditorialHero` components.
- Applied `maxHeight={{ base: "viewport-half", md: "none" }}` and `object-contain` to article images and Mermaid diagrams in `MarkdownRenderer`.
- Verified the fix across mobile, tablet, and desktop viewports using production builds and Playwright.

Challenges:
- Iterated through multiple implementation strategies to satisfy the repository's strict UI anti-pattern audits (which flag arbitrary values) and automated code reviews (which flag modern Tailwind v4 syntax or specificity issues).
- Resolved these by integrating the constraint directly into the primitive layout system (`Box` and `SPACING_MAP`), ensuring type safety and clean responsive overrides.
- Added `viewport-half` (50vh) and `none` design tokens to `src/index.css` and `SPACING_MAP`.
- Updated `Box` layout primitive to handle the new tokens in `maxHeight` prop.
- Applied responsive `maxHeight` constraints to `EditorialHero` and `MarkdownRenderer` images.
- Overhauled `MarkdownRenderer` image implementation with dimension sanitization, horizontal centering, and security attributes.
- Verified fix on mobile (375px) and desktop (1280px) viewports.
arii pushed a commit that referenced this pull request Jun 19, 2026
- Correctly extract base reference from `diffCommand` for context gathering.
- Use `--` in `git diff` to avoid ambiguity with filenames.
- Fix ESLint `no-useless-assignment` error in `resolveImportPath`.
- Ensure robust symbol identification in diff hunks.

These fixes ensure the AI reviewer receives the full source context for
imported symbols, resolving the "hedging" problem identified in PR #2548.

@arii arii left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

ANTI-AI-SLOP\n\n\n## FINDINGS\n\n\n## FINAL RECOMMENDATION\n<Approved | Approved with Minor Changes | Not Approved>\n\n

Inline Comments (Fallback due to Github line resolution errors)

  • :1:

@arii arii left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

ANTI-AI-SLOP\n\n\n## FINDINGS\n\n\n## FINAL RECOMMENDATION\n<Approved | Approved with Minor Changes | Not Approved>\n\n

Inline Comments (Fallback due to Github line resolution errors)

  • :1:

@arii arii left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Automated Review for PR #2548

CI Status: Failing checks detected.

Failing Checks:

  • Deployment Impact Analysis

Recommendation: Please review the failing CI logs and apply fixes.

FINAL RECOMMENDATION

Not Approved

@arii arii left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Automated Review for PR #2548

CI Status: Failing checks detected.

Failing Checks:

  • Deployment Impact Analysis

Recommendation: Please review the failing CI logs and apply fixes.

FINAL RECOMMENDATION

Not Approved

@arii arii left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Comprehensive Review for PR #2548

CI Status: Failing checks detected.

Failing Checks:

  • Deployment Impact Analysis

Recommendation: Please review the failing CI logs and apply fixes before requesting another review.

FINAL RECOMMENDATION

Not Approved

@arii arii closed this Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Oversized images in blog posts dominate the mobile viewport

1 participant