Skip to content

Commit 57d519b

Browse files
Vidminasclaude
andcommitted
feat(portfolio): add design.aspect_ratio knob for card images
Card image dimensions were hardcoded: a fixed-height box (h-48) plus a fixed 3:2 crop (Fill "600x400"). The box ratio therefore tracked card width / column count and rarely matched the crop, so object-cover re-cropped the already cropped image (a double-crop). Add a `design.aspect_ratio` knob (square | landscape | portrait | wide | photo) that mirrors the gallery block's vocabulary and drives BOTH the CSS aspect box and the Fill dimensions from one map, so the box always matches the crop — a single, predictable crop at any width / column count. Defaults to `photo` (3:2, 600x400), preserving the previous appearance, so it's non-breaking. All aspect class strings are literal in the template so Tailwind's scanner emits them. Documents the option in the block README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 68cbf33 commit 57d519b

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

modules/blox/blox/portfolio/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ A flexible, filterable portfolio block for showcasing work with Alpine.js-powere
4343
# text: "Browse All" # Custom text
4444
design:
4545
columns: 3
46+
aspect_ratio: photo # Card image shape: photo (3:2), landscape, square, portrait, wide
4647
fallback_icon: code-bracket # Or: academic-cap, paint-brush, camera, etc.
4748
```
4849
@@ -95,6 +96,7 @@ featured: true
9596
| Parameter | Type | Default | Description |
9697
|-----------|------|---------|-------------|
9798
| `columns` | integer | 3 | Grid columns (2, 3, or 4) |
99+
| `aspect_ratio` | string | `photo` | Card image shape — matches the crop to the box so images aren't double-cropped. One of `photo` (3:2), `landscape` (4:3), `square` (1:1), `portrait` (3:4), `wide` (16:9). |
98100
| `fallback_icon` | string | `code-bracket` | Icon shown when item has no image. Supports all Hugo Blox icon packs (hero, brands, devicon, emoji, custom). Format: `icon-name` or `pack/icon-name` |
99101
| `status_badge.enable` | boolean | true | Show or hide the status badge |
100102

modules/blox/blox/portfolio/block.html

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,28 @@
173173
{{ $fallback_icon = $fallback_raw }}
174174
{{ end }}
175175

176+
{{/* Card image aspect ratio (square | landscape | portrait | wide | photo)
177+
The chosen ratio drives BOTH the CSS aspect box and the `Fill` dimensions,
178+
so the box always matches the crop (one predictable crop at any width /
179+
column count). Every class string is written out literally so Tailwind's
180+
scanner generates the utilities. Photo (3:2) is the default with a fixed 600x400 crop. */}}
181+
{{ $ratio_map := dict
182+
"square" (dict "class" "aspect-square" "fill" "600x600 webp")
183+
"landscape" (dict "class" "aspect-[4/3]" "fill" "600x450 webp")
184+
"portrait" (dict "class" "aspect-[3/4]" "fill" "480x640 webp")
185+
"wide" (dict "class" "aspect-[16/9]" "fill" "800x450 webp")
186+
"photo" (dict "class" "aspect-[3/2]" "fill" "600x400 webp")
187+
}}
188+
{{ $ratio_name := "photo" }}
189+
{{ $ratio_raw := index $design "aspect_ratio" }}
190+
{{ if eq (printf "%T" $ratio_raw) "string" }}
191+
{{ $trimmed := lower (strings.TrimSpace $ratio_raw) }}
192+
{{ if $trimmed }}{{ $ratio_name = $trimmed }}{{ end }}
193+
{{ end }}
194+
{{ $ratio := index $ratio_map $ratio_name | default (index $ratio_map "photo") }}
195+
{{ $ratio_class := index $ratio "class" }}
196+
{{ $ratio_fill := index $ratio "fill" }}
197+
176198
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-16" x-data="{ activeFilter: {{ $default_tag | jsonify }} }">
177199

178200
{{/* Header */}}
@@ -271,7 +293,7 @@ <h2 class="text-3xl sm:text-4xl font-bold text-gray-900 dark:text-white mb-4">
271293
class="group relative flex flex-col bg-white dark:bg-white/[0.03] backdrop-blur-xl rounded-2xl border border-gray-200 dark:border-white/[0.08] overflow-hidden hover:border-primary-500/50 hover:bg-gray-50 dark:hover:bg-white/[0.06] transition-all duration-300 hover:shadow-xl hover:shadow-primary-500/10 card-hover-lift"
272294
>
273295
{{/* Card Header / Image */}}
274-
<div class="relative h-48 overflow-hidden">
296+
<div class="relative {{ $ratio_class }} overflow-hidden">
275297
{{ $image := $item.Resources.GetMatch "{featured,cover,thumbnail}*" }}
276298
{{ if $image }}
277299
{{ if not (reflect.IsImageResourceProcessable $image) }}
@@ -281,7 +303,7 @@ <h2 class="text-3xl sm:text-4xl font-bold text-gray-900 dark:text-white mb-4">
281303
class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
282304
>
283305
{{ else }}
284-
{{ $img := $image.Fill "600x400 webp" }}
306+
{{ $img := $image.Fill $ratio_fill }}
285307
<img
286308
src="{{ $img.RelPermalink }}"
287309
alt="{{ $item.Title }}"

0 commit comments

Comments
 (0)