Shadow DOM and syntax themes


#1

I just started using Atom a little while ago and I thought I’d try my hand at generating a new syntax theme based on some of the customization I’ve been making in my own style sheet and as an introduction/tutorial to hacking bits and pieces of Atom.

However, I’m pretty new to this type of coding and despite searching here for information, I’m still a little confused about the use of shadow DOM in the text editor component. Specifically, when and where I should be using ::shadow as part of the selector in my syntax theme files.

Here’s what I’ve gathered thus far:

Based on this post and on the default theme that gets generated by using the “Package Generator: Generate Syntax Theme” command, it appears that everything in base.less (or whatever equivalent you indicate in the index.less file) shouldn’t need to use ::shadow at all, since syntax themes are already loaded inside the editor’s shadow DOM.

However, it appears as though out that the wrap guide will ignore any style you try to apply to it with, e.g.:

atom-text-editor .wrap-guide { background-color: red; }

Instead, you have to style it with:

atom-text-editor::shadow .wrap-guide { background-color: red; }

The same behavior can be observed for search markers, which leads me to believe that this may have something to do with fact these styles are also defined by the wrap-guide and find-and-replace packages.

This (finally) leads me to a couple of questions:

  1. What is ::shadow doing in this context? We appear to already be inside the shadow DOM. I don’t have to use atom-text-editor::shadow .comment to set the style of comments the way I do in my personal style sheet.

  2. Does it actually have anything to do with the fact that wrap-guide and find-result are also defined in the packages that add this functionality to Atom or is that simply a coincidence?


#2

If you just did atom-text-editor that would mean things inside an atom-text-editor element but outside of a shadow DOM. Since there is no .wrap-guide class element outside of a shadow DOM, the selector wouldn’t apply.

Could you just use .wrap-guide as the selector?

I’m Not a CSS Guy™ so I could be way off the mark …


#3

Using .wrap-guide appears to to the same thing as atom-text-editor .wrap-guide (i.e. it doesn’t fix the “problem”). However, I do have to amend my previous statement that these selectors appear to be ignored completely. If you try to change something like the background color, or width, or anything else that gets set in the wrap-guide package, it gets ignored. If you set something else, e.g. the opacity or border, the style is properly applied (whether or not you’re inside an atom-text-editor element).

Given this, my inclination would be to say this is related to the order in which style affects are applied. That still leaves me wondering how exactly using ::shadow “fixes” the timing issue. Perhaps all shadow styles overwrite non-shadow styles? I’ll have to do a bit more reading on shadow DOM stuff.

Incidentally, proper use of inspect element was very helpful here. I probably should have done that to begin with. I was able to discover that part of the reason I missed the opacity stuff to begin with was because my chosen UI theme was also setting the style of the wrap guide.


#4

Given the new information, I would suspect that this is a CSS specificity issue. Notice that all of the wrap-guide styles are defined with the selector atom-text-editor::shadow .wrap-guide:

So if you just use .wrap-guide as the selector, your selector isn’t at least as specific as the built-in ones and loses the specificity test. If you use atom-text-editor .wrap-guide you’re saying that your styles should apply to an atom-text-editor but without a shadow DOM … which isn’t accurate, so they just don’t even apply.

Perhaps the wrap-guide package styles should be changed to load inside the text editor rather than from the outside too and then they could be made so that they could be overridden easier.