feat(rail-ads): rails responsive que llenan el espacio disponible

- Ancho calculado automaticamente: (viewport - container) / 2 - 20px
- 10px margen del viewport + 10px gap al container
- Selector simplificado: solo altura (250-1050px)
- AdSense usa data-full-width-responsive para adaptarse
- Media query actualizada: oculta en pantallas < 1620px
This commit is contained in:
FrankZamora
2025-11-27 21:55:04 -06:00
parent 070ee7398c
commit 6b6ebd3c6d
3 changed files with 72 additions and 135 deletions

View File

@@ -294,48 +294,27 @@ final class AdsensePlacementRenderer
$topOffset = (int)($settings['behavior']['rail_top_offset'] ?? 300);
$delayEnabled = ($settings['forms']['delay_enabled'] ?? true) === true;
// Dimensiones segun formato
// Soporta anchos: 130, 140, 150, 160, 300, 400, 500, 600px
[$width, $height] = match($format) {
// 130px width
'w130-h300' => [130, 300],
'w130-h400' => [130, 400],
'w130-h500' => [130, 500],
'w130-h600' => [130, 600],
// 140px width
'w140-h300' => [140, 300],
'w140-h400' => [140, 400],
'w140-h500' => [140, 500],
'w140-h600' => [140, 600],
// 150px width
'w150-h300' => [150, 300],
'w150-h400' => [150, 400],
'w150-h500' => [150, 500],
'w150-h600' => [150, 600],
// 160px width (legacy keys)
'slim-small' => [160, 300],
'slim-medium' => [160, 400],
'slim-large' => [160, 500],
'slim-xlarge' => [160, 700],
'wide-skyscraper' => [160, 800],
// 300px width
'w300-h250' => [300, 250],
'half-page' => [300, 600],
'large-skyscraper' => [300, 1050],
// 400px width
'w400-h300' => [400, 300],
'w400-h400' => [400, 400],
'w400-h600' => [400, 600],
// 500px width
'w500-h300' => [500, 300],
'w500-h400' => [500, 400],
'w500-h600' => [500, 600],
// 600px width
'w600-h300' => [600, 300],
'w600-h400' => [600, 400],
'w600-h600' => [600, 600],
// Default: skyscraper 160x600
default => [160, 600],
// Altura del rail segun formato seleccionado
// El ancho es responsive (se ajusta automaticamente al espacio disponible)
$height = match($format) {
'h250' => 250,
'h300' => 300,
'h400' => 400,
'h500' => 500,
'h600' => 600,
'h700' => 700,
'h800' => 800,
'h1050' => 1050,
// Legacy keys para compatibilidad con valores anteriores
'skyscraper', 'slim-large', 'w130-h600', 'w140-h600', 'w150-h600' => 600,
'slim-small', 'w130-h300', 'w140-h300', 'w150-h300' => 300,
'slim-medium', 'w130-h400', 'w140-h400', 'w150-h400' => 400,
'slim-xlarge' => 700,
'wide-skyscraper' => 800,
'w300-h250' => 250,
'half-page' => 600,
'large-skyscraper' => 1050,
default => 600,
};
$scriptType = $delayEnabled ? 'text/plain' : 'text/javascript';
@@ -344,29 +323,35 @@ final class AdsensePlacementRenderer
// === CSS via CSSGenerator (NO hardcodeado) ===
$cssRules = [];
// Estilos base para Rail Ads
// Estilos base para Rail Ads - RESPONSIVE
// El ancho se calcula automaticamente para llenar el espacio disponible
// Formula: (viewport - container) / 2 - margen_exterior(10px) - gap_interior(10px)
$cssRules[] = $this->cssGenerator->generate('.roi-rail-ad', [
'position' => 'fixed',
'top' => $topOffset . 'px',
'width' => $width . 'px',
'width' => 'calc((100vw - var(--roi-container-width-numeric, 1320px)) / 2 - 20px)',
'height' => $height . 'px',
'display' => 'flex',
'justify-content' => 'center',
'align-items' => 'flex-start',
'z-index' => '100',
'transition' => 'top 0.2s ease-out',
'transition' => 'top 0.2s ease-out, width 0.2s ease-out',
'overflow' => 'hidden',
]);
// Posicion rail izquierdo - FIJO en el borde del viewport
// Los Rails NO dependen del container width, siempre estan a 5px del borde
// Posicion rail izquierdo - 10px del borde del viewport
$cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-left', [
'left' => '5px',
'left' => '10px',
]);
// Posicion rail derecho - FIJO en el borde del viewport
// Posicion rail derecho - 10px del borde del viewport
$cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-right', [
'right' => '5px',
'right' => '10px',
]);
// Media query para ocultar en pantallas < 1600px
// NOTA: Media queries se escriben directamente (patron consistente con FeaturedImageRenderer)
$cssRules[] = "@media (max-width: 1599px) {
// Media query para ocultar en pantallas donde no hay espacio suficiente
// Minimo: container(1320) + 2*rail_min(130) + 4*margin(10) = 1320+260+40 = 1620px
$cssRules[] = "@media (max-width: 1619px) {
.roi-rail-ad { display: none !important; }
}";
@@ -377,8 +362,9 @@ final class AdsensePlacementRenderer
/**
* EXCEPCION DOCUMENTADA: CSS inline requerido por Google AdSense
* Los atributos style="display:inline-block;width:Xpx;height:Xpx" son
* especificacion de Google y NO pueden generarse via CSSGenerator.
* Usamos display:block con data-full-width-responsive="true" para que
* el anuncio se adapte automaticamente al ancho del contenedor responsive.
* La altura se controla via el selector de formato.
* Ref: https://support.google.com/adsense/answer/9274516
*/
@@ -386,11 +372,12 @@ final class AdsensePlacementRenderer
if ($leftEnabled) {
$html .= sprintf(
'<div class="roi-rail-ad roi-rail-ad-left">
<ins class="adsbygoogle" style="display:inline-block;width:%dpx;height:%dpx"
data-ad-client="%s" data-ad-slot="%s"></ins>
<ins class="adsbygoogle" style="display:block;height:%dpx"
data-ad-client="%s" data-ad-slot="%s"
data-full-width-responsive="true"></ins>
<script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
</div>',
$width, $height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr
$height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr
);
}
@@ -398,11 +385,12 @@ final class AdsensePlacementRenderer
if ($rightEnabled) {
$html .= sprintf(
'<div class="roi-rail-ad roi-rail-ad-right">
<ins class="adsbygoogle" style="display:inline-block;width:%dpx;height:%dpx"
data-ad-client="%s" data-ad-slot="%s"></ins>
<ins class="adsbygoogle" style="display:block;height:%dpx"
data-ad-client="%s" data-ad-slot="%s"
data-full-width-responsive="true"></ins>
<script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
</div>',
$width, $height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr
$height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr
);
}