Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
f2d317e
Type tidying
frederickobrien Mar 11, 2026
d087f53
Move all column settings into layout config
frederickobrien Mar 11, 2026
744539d
Remove maxWidth wrapper divs
frederickobrien Mar 11, 2026
6eb25a8
Rough first pass
frederickobrien May 19, 2026
211c9c2
Refactor grid centre rule, more breakpoints
frederickobrien May 21, 2026
6471809
Rough implementation of portrait/landscape variants
frederickobrien May 26, 2026
a87148c
Feature specific styling
frederickobrien Jun 11, 2026
dd62136
Use grid module helpers for columns
frederickobrien Jun 23, 2026
231cf02
First, clumsy pass at immersive forking
frederickobrien Jun 23, 2026
39b646d
Distinguish between feature and non-feature immersives
frederickobrien Jun 30, 2026
86a943f
Fix portrait main media config
frederickobrien Jun 30, 2026
05d9d26
Tie main media styling to article arrangement
frederickobrien Jun 30, 2026
0dafbd3
Restore wrapper
frederickobrien Jul 1, 2026
d67d072
Enhance article meta and layout handling for immersive designs
alessiaAmitrano Jul 7, 2026
4afd212
show byline for immersive landscape
alessiaAmitrano Jul 17, 2026
ec86165
show byline and avatar in a row, show series tag, reintroduce borders…
alessiaAmitrano Jul 21, 2026
d582bd9
add testing for new layoutType parameters influencing contributor sho…
alessiaAmitrano Jul 22, 2026
f92e085
Rough first pass
frederickobrien May 19, 2026
ad4cd74
Rough implementation of portrait/landscape variants
frederickobrien May 26, 2026
1eb6a80
Feature specific styling
frederickobrien Jun 11, 2026
adbec3e
Distinguish between feature and non-feature immersives
frederickobrien Jun 30, 2026
57534d9
Tie main media styling to article arrangement
frederickobrien Jun 30, 2026
2c36282
Rebase tidying
frederickobrien Jul 7, 2026
e33d5d1
Rich review tweaks
frederickobrien Jul 16, 2026
eeaa9ce
Caption grid area and meta section
frederickobrien Jul 21, 2026
b0df0eb
make layoutType optional for ArticleMeta web and app components
alessiaAmitrano Jul 28, 2026
dd4af19
make layoutType optional for ArticleTitle and children
alessiaAmitrano Jul 28, 2026
f020894
Merge remote-tracking branch 'origin/portrait-layout' into aa/portrai…
alessiaAmitrano Jul 28, 2026
7c88363
fix issues post merge
alessiaAmitrano Jul 28, 2026
6739f4c
fix duplicate prop in ArticleHeadline component
alessiaAmitrano Jul 28, 2026
7aaa4fa
Rough first pass
frederickobrien May 19, 2026
d693896
Rough implementation of portrait/landscape variants
frederickobrien May 26, 2026
249ea42
Feature specific styling
frederickobrien Jun 11, 2026
4db971e
Distinguish between feature and non-feature immersives
frederickobrien Jun 30, 2026
2d1b937
Tie main media styling to article arrangement
frederickobrien Jun 30, 2026
3107ac9
Rebase tidying
frederickobrien Jul 7, 2026
ebf1fbc
Rich review tweaks
frederickobrien Jul 16, 2026
2100f70
Caption grid area and meta section
frederickobrien Jul 21, 2026
b31f2df
Update immersive ad count test
frederickobrien Jul 29, 2026
a6a17d7
add changes lost during merge
alessiaAmitrano Jul 29, 2026
b1372f6
Merge commit 'b31f2dfb5958c6710a6ce41054eb29969588e941' into aa/portr…
alessiaAmitrano Jul 29, 2026
7e700b3
remove duplicate identifier
alessiaAmitrano Jul 29, 2026
c19bea4
Rough first pass
frederickobrien May 19, 2026
b73ce4a
Rough implementation of portrait/landscape variants
frederickobrien May 26, 2026
a316395
Feature specific styling
frederickobrien Jun 11, 2026
b950785
Distinguish between feature and non-feature immersives
frederickobrien Jun 30, 2026
691fcea
Tie main media styling to article arrangement
frederickobrien Jun 30, 2026
0904753
Rebase tidying
frederickobrien Jul 7, 2026
6041b44
Rich review tweaks
frederickobrien Jul 16, 2026
8f76f07
Caption grid area and meta section
frederickobrien Jul 21, 2026
4f66342
Update immersive ad count test
frederickobrien Jul 29, 2026
396b1a8
Merge branch 'portrait-layout' into aa/portrait-layout-continued
frederickobrien Jul 30, 2026
457487d
Update ArticleHeadline.tsx
frederickobrien Jul 30, 2026
59e1d12
Merge branch 'portrait-layout' of https://github.com/guardian/dotcom-…
DanielCliftonGuardian Jul 30, 2026
6c16119
Apply suggestions from code review
frederickobrien Jul 30, 2026
8d18e72
Merge pull request #16482 from guardian/aa/portrait-layout-continued
frederickobrien Jul 30, 2026
8e1bd1a
Simplify `shouldShowAvatar` switch
frederickobrien Jul 30, 2026
265d0f2
Remove leftover debug crop and duplicate CSS from immersive grid layout
DanielCliftonGuardian Jul 30, 2026
724623d
Fix immersive content overlapping the Labs header
DanielCliftonGuardian Jul 30, 2026
996fd99
Preserve immersive main media aspect ratios
DanielCliftonGuardian Jul 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dotcom-rendering/playwright/tests/commercial.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ test.describe('Commercial E2E tests', () => {
'merchandising',
];

const totalSlotsExpected = 15; // All slots, even if unfilled ie. `display: none`
const totalSlotsExpected = 16; // All slots, even if unfilled ie. `display: none`
const inlineSlots = totalSlotsExpected - fixedSlots.length;

// We are excluding survey slot as they can be switched off
Expand Down
2 changes: 1 addition & 1 deletion dotcom-rendering/playwright/tests/lightbox.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ test.describe('Lightbox', () => {

// Open lightbox by clicking on the fourth image within the article body
// Lightbox should open at the fifth image as the first image is the main media image
await page.locator('article img').nth(3).click({ force: true });
await page.locator('button.open-lightbox').nth(4).click();

await expectToBeVisible(page, '#gu-lightbox');

Expand Down
153 changes: 58 additions & 95 deletions dotcom-rendering/src/components/ArticleHeadline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
until,
} from '@guardian/source/foundations';
import { grid } from '../../src/grid';
import { type LayoutType } from '../layouts/lib/articleArrangements';
import { interactiveLegacyClasses } from '../layouts/lib/interactiveLegacyStyling';
import { getAgeWarning } from '../lib/age-warning';
import {
Expand All @@ -27,7 +28,6 @@ import {
ArticleSpecial,
Pillar,
} from '../lib/articleFormat';
import { getZIndex } from '../lib/getZIndex';
import { palette as themePalette } from '../palette';
import type { StarRating as Rating } from '../types/content';
import type { TagType } from '../types/tag';
Expand All @@ -39,6 +39,7 @@ import { StarRating } from './StarRating/StarRating';
type Props = {
headlineString: string;
format: ArticleFormat;
layoutType?: LayoutType;
byline?: string;
tags: TagType[];
webPublicationDateDeprecated: string;
Expand Down Expand Up @@ -214,30 +215,20 @@ const invertedStyles = css`
box-decoration-break: clone;
`;

const immersiveStyles = css`
min-height: 112px;
padding-bottom: ${space[6]}px;
padding-left: ${space[1]}px;

${from.mobileLandscape} {
padding-left: ${space[3]}px;
}

${from.tablet} {
padding-left: ${space[1]}px;
}

margin-right: ${space[5]}px;
`;

const darkBackground = css`
background-color: ${themePalette('--headline-background')};
`;

const invertedText = css`
white-space: pre-wrap;
padding-bottom: ${space[1]}px;
padding-right: ${space[1]}px;
${from.desktop} {
color: white;
background-color: black;
white-space: pre-wrap;
padding-bottom: ${space[1]}px;
padding-right: ${space[1]}px;
margin-left: -10px;
padding-left: 10px;
}
`;

const maxWidth = css`
Expand All @@ -255,35 +246,6 @@ const invertedWrapper = css`
margin-left: 6px;
`;

const immersiveWrapper = css`
/*
Make sure we vertically align the headline font with the body font
*/
margin-left: 6px;

${from.tablet} {
margin-left: 16px;
}

${from.leftCol} {
margin-left: 25px;
}

/*
We need this grow to ensure the headline fills the main content column
*/
flex-grow: 1;
/*
This z-index is what ensures the headline text shows above the pseudo black
box that extends the black background to the right
*/
z-index: ${getZIndex('articleHeadline')};

${until.mobileLandscape} {
margin-right: 40px;
}
`;

// Due to MainMedia using position: relative, this seems to effect the rendering order
// To mitigate we use z-index
// TODO: find a cleaner solution
Expand All @@ -292,59 +254,58 @@ const zIndex = css`
`;

const ageWarningMargins = (format: ArticleFormat) => {
if (format.design === ArticleDesign.Gallery) {
if (
format.design === ArticleDesign.Gallery ||
format.display === ArticleDisplay.Immersive
) {
return '';
}
return format.display === ArticleDisplay.Immersive
? css`
margin-left: 0px;
margin-bottom: 0px;

${from.tablet} {
margin-left: 10px;
}
return css`
margin-top: 12px;
margin-left: -10px;
margin-bottom: 6px;

${from.leftCol} {
margin-left: 20px;
}
`
: css`
margin-top: 12px;
margin-left: -10px;
margin-bottom: 6px;

${from.tablet} {
margin-left: -20px;
}
${from.tablet} {
margin-left: -20px;
}

${from.leftCol} {
margin-left: -10px;
margin-top: 0;
}
`;
${from.leftCol} {
margin-left: -10px;
margin-top: 0;
}
`;
};

const backgroundStyles = css`
background-color: ${themePalette('--age-warning-wrapper-background')};
`;

const WithAgeWarning = ({
tags,
webPublicationDateDeprecated,
format,
children,
snapToInverted = false,
}: {
tags: TagType[];
webPublicationDateDeprecated: string;
format: ArticleFormat;
children: React.ReactNode;
snapToInverted?: boolean;
}) => {
const age = getAgeWarning(tags, webPublicationDateDeprecated);

if (age) {
return (
<>
<div css={[backgroundStyles, ageWarningMargins(format)]}>
<div
css={[
ageWarningMargins(format),
snapToInverted
? css`
${from.desktop} {
margin-left: -10px;
}
`
: '',
]}
>
<AgeWarning age={age} />
</div>
{children}
Expand Down Expand Up @@ -433,13 +394,15 @@ const galleryStyles = css`
export const ArticleHeadline = ({
headlineString,
format,
layoutType,
tags,
byline,
webPublicationDateDeprecated,
hasAvatar,
isMatch,
starRating,
}: Props) => {
const isInverted = layoutType === 'immersiveLandscapeDefault';
switch (format.display) {
case ArticleDisplay.Immersive: {
switch (format.design) {
Expand All @@ -465,12 +428,13 @@ export const ArticleHeadline = ({
format.theme === ArticleSpecial.Labs
? labsFont
: headlineFont(format),
invertedText,
css`
color: ${themePalette(
'--headline-colour',
)};
`,
isInverted
? [invertedText, darkBackground]
: css`
color: ${themePalette(
'--headline-colour',
)};
`,
]}
>
{headlineString}
Expand All @@ -496,16 +460,17 @@ export const ArticleHeadline = ({
webPublicationDateDeprecated
}
format={format}
snapToInverted={true}
>
<h1
css={[
immersiveWrapper,
darkBackground,
css`
color: ${themePalette(
'--headline-colour',
)};
`,
isInverted
? [invertedText, darkBackground]
: css`
color: ${themePalette(
'--headline-colour',
)};
`,
]}
>
<span
Expand All @@ -514,8 +479,6 @@ export const ArticleHeadline = ({
? jumboLabsFont
: headlineFont(format),
maxWidth,
invertedStyles,
immersiveStyles,
displayBlock,
]}
>
Expand Down
Loading
Loading