1
1
import { css , type Interpolation } from '@emotion/react' ;
2
2
import type { SlotName } from '@guardian/commercial' ;
3
- import { adSizes , constants } from '@guardian/commercial' ;
3
+ import { adSizes } from '@guardian/commercial' ;
4
4
import {
5
5
between ,
6
6
breakpoints ,
@@ -92,6 +92,10 @@ type Props = DefaultProps &
92
92
93
93
const halfPageAdHeight = adSizes . halfPage . height ;
94
94
95
+ /** Calculates the minimum height for an ad slot. Used to avoid CLS */
96
+ const getMinHeight = ( adHeight : number , padding ?: number ) : number =>
97
+ adHeight + labelHeight + ( padding ?? 0 ) ;
98
+
95
99
const outOfPageStyles = css `
96
100
height : 0 ;
97
101
` ;
@@ -111,7 +115,7 @@ const topAboveNavContainerStyles = css`
111
115
* render first, we need to reserve space for the ad to avoid CLS.
112
116
*/
113
117
const showcaseRightColumnContainerStyles = css `
114
- min-height : ${ halfPageAdHeight + labelHeight } px;
118
+ min-height : ${ getMinHeight ( halfPageAdHeight ) } px;
115
119
` ;
116
120
117
121
const showcaseRightColumnStyles = css `
@@ -131,16 +135,18 @@ const merchandisingAdContainerStyles = css`
131
135
132
136
const merchandisingAdStyles = css `
133
137
position : relative;
134
- min-height : ${ adSizes . billboard . height + labelHeight } px;
135
- margin : 12 px auto;
138
+ min-height : ${ getMinHeight ( adSizes . billboard . height , space [ 3 ] ) } px;
139
+ margin : ${ space [ 3 ] } px auto;
136
140
max-width : ${ breakpoints [ 'wide' ] } px;
137
141
overflow : hidden;
142
+ padding-bottom : ${ space [ 3 ] } px;
138
143
139
144
${ from . desktop } {
140
145
margin : 0 ;
141
- padding-bottom : 20 px ;
142
- min-height : ${ adSizes . billboard . height + labelHeight + 20 } px;
146
+ padding-bottom : ${ space [ 5 ] } px ;
147
+ min-height : ${ getMinHeight ( adSizes . billboard . height , space [ 5 ] ) } px;
143
148
}
149
+
144
150
& : not (.ad-slot--fluid ).ad-slot--rendered {
145
151
${ between . phablet . and . desktop } {
146
152
display : none;
@@ -171,7 +177,7 @@ const liveblogInlineContainerStyles = css`
171
177
172
178
const liveblogInlineAdStyles = css `
173
179
position : relative;
174
- min-height : ${ adSizes . mpu . height + labelHeight } px;
180
+ min-height : ${ getMinHeight ( adSizes . mpu . height ) } px;
175
181
background-color : ${ schemedPalette ( '--ad-background-article-inner' ) } ;
176
182
177
183
${ until . tablet } {
@@ -181,7 +187,7 @@ const liveblogInlineAdStyles = css`
181
187
182
188
const liveblogInlineMobileAdStyles = css `
183
189
position : relative;
184
- min-height : ${ adSizes . outstreamMobile . height + labelHeight } px;
190
+ min-height : ${ getMinHeight ( adSizes . outstreamMobile . height ) } px;
185
191
186
192
${ from . tablet } {
187
193
display : none;
@@ -190,32 +196,27 @@ const liveblogInlineMobileAdStyles = css`
190
196
191
197
const mobileFrontAdStyles = css `
192
198
position : relative;
193
- min-height : ${ adSizes . mpu . height + labelHeight } px;
199
+ min-height : ${ getMinHeight ( adSizes . mpu . height , space [ 3 ] ) } px;
194
200
min-width : 300px ;
195
201
width : 300px ;
196
- margin : 12px auto;
202
+ margin : ${ space [ 3 ] } px auto;
203
+ padding-bottom : ${ space [ 3 ] } px;
197
204
198
205
${ from . tablet } {
199
206
display : none;
200
207
}
201
208
` ;
202
209
203
- const frontsBannerPaddingHeight = 20 ;
204
- const frontsBannerMinHeightTablet =
205
- adSizes . leaderboard . height + labelHeight + frontsBannerPaddingHeight ;
206
- const frontsBannerMinHeight =
207
- adSizes . billboard . height + labelHeight + frontsBannerPaddingHeight ;
208
-
209
210
const frontsBannerAdTopContainerStyles = css `
210
211
display : none;
211
212
${ from . tablet } {
212
213
display : flex;
213
214
justify-content : center;
214
- min-height : ${ frontsBannerMinHeightTablet } px;
215
+ min-height : ${ getMinHeight ( adSizes . leaderboard . height , space [ 6 ] ) } px;
215
216
background-color : ${ schemedPalette ( '--ad-background' ) } ;
216
217
}
217
218
${ from . desktop } {
218
- min-height : ${ frontsBannerMinHeight } px;
219
+ min-height : ${ getMinHeight ( adSizes . billboard . height , space [ 6 ] ) } px;
219
220
}
220
221
` ;
221
222
@@ -240,11 +241,11 @@ const frontsBannerCollapseStyles = css`
240
241
241
242
const frontsBannerAdStyles = css `
242
243
position : relative;
243
- min-height : ${ frontsBannerMinHeightTablet } px;
244
+ min-height : ${ getMinHeight ( adSizes . leaderboard . height , space [ 6 ] ) } px;
244
245
max-width : ${ adSizes . leaderboard . width } px;
245
- max-height : ${ adSizes . leaderboard . height + labelHeight } px;
246
246
overflow : hidden;
247
- padding-bottom : ${ frontsBannerPaddingHeight } px;
247
+ padding-bottom : ${ space [ 6 ] } px;
248
+
248
249
${ from . desktop } {
249
250
/* No banner should be taller than 600px */
250
251
max-height : ${ 600 + labelHeight } px;
@@ -254,7 +255,7 @@ const frontsBannerAdStyles = css`
254
255
255
256
const articleEndAdStyles = css `
256
257
position : relative;
257
- min-height : ${ adSizes . outstreamDesktop . height + labelHeight } px;
258
+ min-height : ${ getMinHeight ( adSizes . outstreamDesktop . height ) } px;
258
259
259
260
& .ad-slot--fluid {
260
261
min-height : 450px ;
@@ -263,7 +264,7 @@ const articleEndAdStyles = css`
263
264
264
265
const mostPopAdStyles = css `
265
266
position : relative;
266
- min-height : ${ adSizes . mpu . height + labelHeight } px;
267
+ min-height : ${ getMinHeight ( adSizes . mpu . height ) } px;
267
268
min-width : ${ adSizes . mpu . width } px;
268
269
max-width : ${ adSizes . mpu . width } px;
269
270
text-align : center;
@@ -277,7 +278,7 @@ const mostPopAdStyles = css`
277
278
` ;
278
279
279
280
const mostPopContainerStyles = css `
280
- min-height : ${ adSizes . mpu . height + labelHeight } px;
281
+ min-height : ${ getMinHeight ( adSizes . mpu . height ) } px;
281
282
min-width : ${ adSizes . mpu . width } px;
282
283
width : fit-content;
283
284
max-width : ${ adSizes . mpu . width } px;
@@ -291,7 +292,7 @@ const mostPopContainerStyles = css`
291
292
` ;
292
293
293
294
const liveBlogTopAdStyles = css `
294
- min-height : ${ adSizes . mpu . height + labelHeight } px;
295
+ min-height : ${ getMinHeight ( adSizes . mpu . height ) } px;
295
296
min-width : ${ adSizes . mpu . width } px;
296
297
width : fit-content;
297
298
max-width : ${ adSizes . mpu . width } px;
@@ -379,7 +380,7 @@ const mobileStickyAdStylesFullWidth = css`
379
380
` ;
380
381
381
382
const crosswordBannerMobileAdStyles = css `
382
- min-height : ${ adSizes . mobilesticky . height + constants . AD_LABEL_HEIGHT } px;
383
+ min-height : ${ getMinHeight ( adSizes . mobilesticky . height ) } px;
383
384
` ;
384
385
385
386
const AdSlotWrapper = ( {
@@ -583,7 +584,7 @@ export const AdSlot = ({
583
584
}
584
585
case 'top-above-nav' : {
585
586
return (
586
- < AdSlotWrapper css = { [ topAboveNavContainerStyles ] } >
587
+ < AdSlotWrapper css = { topAboveNavContainerStyles } >
587
588
< div
588
589
id = "dfp-ad--top-above-nav"
589
590
className = { [
@@ -626,15 +627,15 @@ export const AdSlot = ({
626
627
}
627
628
case 'merchandising-high' : {
628
629
return (
629
- < AdSlotWrapper css = { [ merchandisingAdContainerStyles ] } >
630
+ < AdSlotWrapper css = { merchandisingAdContainerStyles } >
630
631
< div
631
632
id = "dfp-ad--merchandising-high"
632
633
className = { [
633
634
'js-ad-slot' ,
634
635
'ad-slot' ,
635
636
'ad-slot--merchandising-high' ,
636
637
] . join ( ' ' ) }
637
- css = { [ merchandisingAdStyles ] }
638
+ css = { merchandisingAdStyles }
638
639
data-link-name = "ad slot merchandising-high"
639
640
data-name = "merchandising-high"
640
641
data-refresh = "false"
@@ -654,7 +655,7 @@ export const AdSlot = ({
654
655
'ad-slot' ,
655
656
'ad-slot--merchandising' ,
656
657
] . join ( ' ' ) }
657
- css = { [ merchandisingAdStyles ] }
658
+ css = { merchandisingAdStyles }
658
659
data-link-name = "ad slot merchandising"
659
660
data-name = "merchandising"
660
661
data-testid = "slot"
@@ -685,7 +686,7 @@ export const AdSlot = ({
685
686
'ad-slot--rendered' ,
686
687
hasPageskin && 'ad-slot--collapse' ,
687
688
] . join ( ' ' ) }
688
- css = { [ frontsBannerAdStyles ] }
689
+ css = { frontsBannerAdStyles }
689
690
data-link-name = { `ad slot ${ advertId } ` }
690
691
data-name = { `${ advertId } ` }
691
692
data-testid = "slot"
@@ -773,7 +774,7 @@ export const AdSlot = ({
773
774
'ad-slot--liveblog-top' ,
774
775
'ad-slot--rendered' ,
775
776
] . join ( ' ' ) }
776
- css = { [ liveBlogTopAdStyles ] }
777
+ css = { liveBlogTopAdStyles }
777
778
data-link-name = "ad slot liveblog-top"
778
779
data-name = "liveblog-top"
779
780
data-testid = "slot"
@@ -797,7 +798,7 @@ export const AdSlot = ({
797
798
'mobile-only' ,
798
799
'ad-slot--rendered' ,
799
800
] . join ( ' ' ) }
800
- css = { [ mobileFrontAdStyles ] }
801
+ css = { mobileFrontAdStyles }
801
802
data-link-name = { `ad slot ${ advertId } ` }
802
803
data-name = { advertId }
803
804
data-testid = "slot"
@@ -841,7 +842,7 @@ export const AdSlot = ({
841
842
'ad-slot--article-end' ,
842
843
'ad-slot--rendered' ,
843
844
] . join ( ' ' ) }
844
- css = { [ articleEndAdStyles ] }
845
+ css = { articleEndAdStyles }
845
846
data-link-name = "ad slot article-end"
846
847
data-name = "article-end"
847
848
data-testid = "slot"
@@ -861,7 +862,7 @@ export const AdSlot = ({
861
862
'ad-slot--crossword-banner-mobile' ,
862
863
'ad-slot--rendered' ,
863
864
] . join ( ' ' ) }
864
- css = { [ crosswordBannerMobileAdStyles ] }
865
+ css = { crosswordBannerMobileAdStyles }
865
866
data-link-name = "ad slot crossword-banner-mobile"
866
867
data-name = "crossword-banner-mobile"
867
868
data-testid = "slot"
0 commit comments