components icon indicating copy to clipboard operation
components copied to clipboard

bug(Youtube player): width not responsive

Open Eraldo opened this issue 1 year ago • 9 comments
trafficstars

Is this a regression?

  • [X] Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

I only noticed it after a couple of upgrades, so I don't know exactly.

Description

Related: https://github.com/angular/components/issues/28489 However the workarounds that are mentioned there don't work anymore.

Setting width="100%" does not work as the input is transformed into a number type: https://github.com/angular/components/blob/main/src/youtube-player/youtube-player.ts#L148

What is the solution approach to get the component to display responsively so it shows up correctly on both mobile and desktop?

Reproduction

StackBlitz link: https://stackblitz.com/edit/angular-youtube-player-responsive-issue?file=src%2Fmain.ts Steps to reproduce:

  1. Open the StackBlitz link
  2. Optionally make the preview window smaller.
  3. Check the browser preview to confirm that the video is overflowing the page width.

Expected Behavior

It shoult take the whole width of the screen

Actual Behavior

The video overflows the with of its parent elements.

Environment

  • Angular: 17.0.1
  • Browser(s): Stackblitz bundled
  • Operating System (e.g. Windows, macOS, Ubuntu): online

Eraldo avatar Apr 05 '24 11:04 Eraldo

Anyone looking for a temporary fix until the bug is resolved:

  • In your component HTML add [width]="width" attribute to the <youtube-player> element
  • In your component TS add:
    • In the constructor: private winRef: WindowRef = inject(WindowRef);
    • public width: number; this.width = this.winRef.nativeWindow?.innerWidth ?? 0;.
  • If you need to compensate for some padding or margin in your page, just subtract that from the width value.

kevinriemens avatar Apr 08 '24 14:04 kevinriemens

Now only the width and height numbers work, because now the check happens like this this._height = height == null || isNaN(height) ? DEFAULT_PLAYER_HEIGHT : height;

you can create a responsive container and use ResizeObserver to get its size. for example

function resizeObservable(elem: Element, options?: ResizeObserverOptions): Observable<ResizeObserverEntry> { return new Observable((subscriber) => { const resizeObserver = new ResizeObserver(([entry]) => { subscriber.next(entry); }); resizeObserver.observe(elem, options); return function unsubscribe(): void { resizeObserver.unobserve(elem); }; }); }

and in component

<div #playerContainer style="width=50%; height: 50%"><youtube-player [height]="playerHeight()" [width]="playerWidth()" [videoId]="videoId"></youtube-player>

@ViewChild('playerContainer', {static: true}) public playerContainerRef?: ElementRef<HTMLElement>; public playerWidth = signal(NaN); public playerHeight = signal(NaN); ngOnInit(): void { if (this.playerContainerRef) { resizeObservable(this.playerContainerRef.nativeElement) .pipe( map(({ contentRect: { height, width } }) => ({ height, width })), distinctUntilChanged((a, b) => a.height === b.height && a.width === b.width), takeUntilDestroyed(this.destroyRef), ) .subscribe(({height,width}) => { this.playerHeight.set(height); this.playerWidth.set(width); }); } }

StepaZol avatar Apr 21 '24 10:04 StepaZol

For now I created a custom component with a wrapper and I'm setting the wrapper height and width on it instead of the angular video player component. And then I set the iframe full width/height.

  youtube-player > *,
  youtube-player iframe {
    width: 100% !important;
    height: 100% !important;
  }

This is a another workaround it seems. I'm still looking forward to having an official way to do it. ;)

Eraldo avatar Apr 25 '24 13:04 Eraldo

I am also experiencing this issue. Before I was able to set width 100%, now it defaults to 640 because it is no longer a number. Thanks for the worksarounds. I hope the maintainer can allow us to use width 100% again.

mattiLeBlanc avatar May 31 '24 10:05 mattiLeBlanc

We ran into the same issue that youtube videos stopped being responsive. Looks like the issue originated with this commit https://github.com/angular/components/commit/381a65f33d87c885235d2076297f092d6c218bae . Technically, only pixel values are allowed for width/height according to the html5 spec, so this change makes sense. However, browsers seem to tolerate % values. Any thoughts @crisbeto ?

MarcoGlauser avatar Jun 10 '24 03:06 MarcoGlauser

The proposed workarounds seem to mess with aspect ratio or require typescript, so here is another one that only uses css and keeps a fixed aspect ratio:

youtube-player {
  position: relative;
  padding-top: 56.25%; // 16:9 ratio
}

:host ::ng-deep youtube-player > *, {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%!important;
  height: 100%!important;
}

:host ::ng-deep youtube-player iframe {
  width: 100% !important;
  height: 100% !important;
}

One downside: you need to know the aspect ratio beforehand and calculate padding-top on the youtube-player styling accordingly.

Please fix this, responsiveness should be supported by default in 2024.

hassmal avatar Jun 19 '24 08:06 hassmal

Issue is still present in 18.1.1.

String inputs "width" and "height" where we could set "200px" or "100%" would be perfect.

martinboue avatar Jul 17 '24 17:07 martinboue