Injection and styling a button into the YouTube player
Hi! I'm trying to inject a button into the YouTube player, next to the Miniplayer button, but so far I've been unsucessful at styling. Here is my current code:
This code seems to insert the button at the right place, but I don't understand how to change the size of the plasmo-csui tag created by Plasmo. I tried to access it in the stylesheet, but to no avail:
How does that work exactly? I'm aware of the existence of this page: https://docs.plasmo.com/framework/content-scripts-ui/styling
But I find it quite obscure. An example would definitely help! ๐ Thanks!
Plasmo Docs
Styling Plasmo CSUI โ Plasmo
Plasmo CSUI's built-in Root Container allows extension developers to safely style their components.
98 Replies
okay, I just wasted 2 days trying to understand this. I'm willing to pay 100 euros for a solution. I just need to understand how to insert that damn button in the player...
Oh now I got it
I'm not a React expert sadly ๐
but I don't understand how to change the size of the plasmo-csui tag created by PlasmoAt this point it's a matter of CSS debugging in the devtools Also, it's seems somewhat related to an issue I've had recently https://discord.com/channels/946290204443025438/1104151734848323634/1104173756638830602
done
How can style this plasmo-csui element?
The beautiful thing with CSS is that you can override everything
okay, trying that. It doesn't seem to affect the element but maybe it has something to do with the way I import my style sheet? I'll check the docs quickly to make sure it's working
Can you link to the repo?
sure I can share it, give me a minute
yeah no the css seems to be working, doing this:
works, but the size of youtube-settings-button-container doesn't change for some reason.
Let me create a repo on github quickly.
@tetec1 has reached level 2. GG!
You could also get assisted by ChatGPT, just saying ๐
GitHub
GitHub - TasseDeCafe/fluentsubs-next
Contribute to TasseDeCafe/fluentsubs-next development by creating an account on GitHub.
I tried, I have access to the gpt-4 API... it didn't really help for this specific problem
or maybe my prompts are shit
I don't know whether
SettingsButton.scss
will pose an issue being in contents/
, worth asking @louisokay, what's the standard way of adding stylesheets?
Plasmo generally scans the
contents/
to see any .ts
/.tsx
/.svelte
/.vue
files to convert into content scripts
No idea for the "standard", but you can just put it under src/
๐คจ
The file doesn't exist
right sorry, but it's not being used anywhere. I deleted it, it didn't seem to change anything
deleted the line*
You need to examine how the surrounding elements affect the element Plasmo generated
.
but isn't this element "isolated" from the rest because it'a shadow root?
Having overly-specific selectors is a bad idea in CSS
The inner parts are isolated, but Plasmo has to inject it to the page to be a part of the DOM, right?
Also, keep in mind that YouTube is SPA
yes, but how can I style it? The CSS doesn't seem to be affecting it.
okay, I'm not sure what that implies here.
I'm not sure how Plasmo "intends" you to style the component, but you can use classes in the component and then
okay, I just tried that, but now the button doesn't appear at all anymore.
It might yes - I generally add stuff in a /core or /styles folder, so that the entry folder is reserved to avoid any complication
The
#youtube-settings-button-container
has to appear by itself pal, that's what gets injected in the DOMAnd wowza this thread is long lol took my machine a minute to load the chat history
sorry I'm a super noob in CSS, I don't understand your answer.
Oh I see, you're new to web dev
well, frontend stuff...
especially mixing a bunch of new things like that got me overwhelmed haha
I think you should first learn some CSS fundamentals ๐
HTML/CSS
okay, thank you. I'll try to move it there and update the import.
Gave +1 Rep to @louis
I've been a web dev for over a decade ๐
I mean I understand the basic ideas, but I kinda get how the basic stuff works, but those libraries create new layer of abstraction that make things less easy to understand. Sorry to bother you guys, I've been looking at this plasmo-csui for 2 days now and I just don't see what I have to do. :)))
That's what Plasmo is doing behind the scenes https://www.youtube.com/watch?v=2I7uX8m0Ta0
Web Dev Simplified
YouTube
Learn Web Components In 25 Minutes
React was the framework that really popularized component driven development, but they werenโt the first and are definitely not the only tool for creating components. JavaScript actually has its own built in way to create components called web components which have many of the same benefits of React components. In this video I show you how to cr...
Salesforce Developers
YouTube
Explaining the Shadow DOM | Developer Quick Takes
Understand what Shadow DOM is, and how Lightning web components leverage it to encapsulate componentโs markup, CSS and behaviour.
Links: Using Shadow DOM (https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM)
Track: BeatFort - Rampant Sunrise
Music provided by Ninety9Lives
Stream / Free Download: 99l.tv/rampantsunriseYU
I linked to videos because that's my preferred style of learning, but if you're more of a reader person, feel free to look up these topics
no I like videos, that's great
@tetec1 has reached level 3. GG!
Some great CSS channels are https://youtube.com/@kevinpowell , https://youtube.com/@webdevsimplified
YouTube
Kevin Powell
Helping you learn how to make the web, and make it look good while you're at it.
With videos every Tuesday and Thursday, I'll be bringing you How Tos and Tutorials, as well as simple tips and tricks, with a big focus on helping people see how wonderful CSS is!
YouTube
Web Dev Simplified
Web Dev Simplified is all about teaching web development skills and techniques in an efficient and practical manner. If you are just getting started in web development Web Dev Simplified has all the tools you need to learn the newest and most popular technologies to convert you from a no stack to full stack developer. Web Dev Simplified also dee...
okay, so I moved the scss to a new styles folder, and imported it correctly, that doesn't seem to affect anything so far
thanks, I knew about Web Dev Simplified, I watched one of his videos some time ago
Gave +1 Rep to @avi12
Like I said, you have to check how would these surrounding elements affect
<plasmo-csui>
For example, some elements you are injecting into might actually be https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/FlexboxFlexbox - Learn web development | MDN
That concludes our tour of the basics of Flexbox. We hope you had fun and will have a good play around with it as you proceed further with your learning. Next, we'll have a look at another important aspect of CSS layouts: CSS Grids.
And guess what, both channels cover flex boxes very deeply ๐
okay, but how do I check that? I'm not even sure how I can see that in the dev tools. Also, why is it that plasmo-csui can't be style at all? I tried applying a background color, it doesn't change.
I believe you can technically style
plasmo-csui
directly, but it's a better practice to select an element by other selectors if you can
Since plasmo-csui
is not a native HTML element
What's important is not what <plasmo-csui>
is but rather what's its container
For example, if you need to inject into a flex box, you need to understand how flex box works to make the CSUI container look rightI see, I tried to style it with the id, but it also doesn't see to be affected by the css:
`
the plasmo-inline element can be styled though
but wouldn't it then make sense to let flexbox apply to the button directly instead of isolating it?
If I understand correctly, your CSUI needs to be injected into
Not only would it make sense, that's what you have to do
So you're trying to inject to the right of the mini player toggler?
I'd like it to be there, and have a little clickable button there
yes
getInlineAnchor
refers to the container element
What's the mini player toggler's container?I found a section of the docs that explains that you can mount without a shadow root, I tried it, but it seems to overlay instead of creating and inline element
and well, I didn't see how to change that behavior
You do need the inline thingy
the class is "ytp-right-controls"
Yup
So what does
const getInlineAnchor: PlasmoGetInlineAnchor
need to return?document.querySelector("div.ytp-chrome-controls > div.ytp-right-controls");
?
damn that actually improved it, I thought I tried that...
Like I said, you need to learn CSS fundamentals ๐
so I should always try to use as few selectors as possible?
But, there is a catch
indeed
Since you're developing an extension that hijacks a DOM of a web page that can be changed at any point, you want your selectors as resilient as possible
What if the user loads up
https://youtube.com
?ah you mean the main page, let's see
Also, what if you navigate from the main page to a video?
okay, so the element does get injected on the main page, but it shouldn't. It's not visible though.
Exactly
navigating to a video works
Does navigating from a video to
/
and to another video works as well?YouTube
Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
Not a great idea
yep that works
What if
/results
?
AKA search pageyes, it's also there.
Restricting to only run on
/watch
page load means that the ext will only run when the user loads up a video, i.e. if he loads up /
and then navigates to a video, the button won't get injected
How about /feed/subscriptions
?so what's the solution here? Try to add a condition that looks for an element that indicates that I'm watching video in the extended view?
(not sure about the name here)
If YouTube was an MPA, as supposed to an SPA, it would work great and it would save us a lot of headache, but that's sadly not the case
okay so it seems to be only visible when I want it, after testing your urls
but indeed it doesn't need to be injected in those pages for no reason
No, it's more complicated
Do you know what is SPA?
What about channel pages?
@avi12 has reached level 27. GG!
yes, I know what it means but I'm not sure what that implies here
Single Page Application
When you navigate in YouTube, YouTube doesn't actually reload the page but rather only changes a section of the DOM
I see
@tetec1 has reached level 4. GG!
Your ext needs to take it into account
Perhaps the ideal solution is https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver , which is my favorite DOM API
MutationObserver - Web APIs | MDN
The MutationObserver interface provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature, which was part of the DOM3 Events specification.
ah I saw this mentioned in the docs, didn't get it
thanks for the link, I'll read all that
Reading is not enough, look up a tutorial, perhaps a video tutorial
MutationObserver is one of the most powerful DOM APIs out there
yes, the thing I find challenging with CSS is that it's not so easy to debug, there are often no errors, it simply... doesn't look correct.
okay, that will probably be useful
One last thing I noticed is that simply using "ytp-right-controls" as a query selector doesn't work, but "div.ytp-right-controls" does. Do you know why?
I agree, CSS is one of the strangest languages out there, if one can even call it a "programming language"
I mean
ytp-right-controls
is a class, so you must target with the class selector, i.e. .ytp-right-controls
right...
okay, I need a break. But you solved my problem (and gave me lots of useful links). Thank you!
No problem, I'll keep answering so long I'm available ๐ซก
You can refer to a repo of mine https://github.com/avi12/youtube-auto-hd
GitHub
GitHub - avi12/youtube-auto-hd: A simple browser extension for chan...
A simple browser extension for changing YouTube videos' quality based on FPS. - GitHub - avi12/youtube-auto-hd: A simple browser extension for changing YouTube videos' quality based on FPS.
right thanks! I was actually looking at it yesterday. I'll clone it later to try to understand how it works. Having a non-trivial example to play with is useful.