Wildcard CSS Selectors in Mobile Layouts

Greetings,

This is a request for help debugging a CSS selector for keyboard style, or to determine if wildcard selectors are just not an option. In a recent keyboard PR (GFF Amharic v3.0) the keyboard .css file grew to 14,600+ lines, but could be reduced to 500-1,000 lines if I could get wildcards working. What I think should work would be a selector like:

 div[id*='U_1200']
   { background: #e2f0cb ; color: black ; }

which would replace layer-specific statements:

 div#popup-default-U_1200,
 div#popup-ሀ-U_1200,
 div#popup-ለ-U_1200,
 div#popup-ሐ-U_1200,
      ⋮

Unfortunately, the wildcard equivalent doesn’t work in the web tester. To look into it, I copied the HTML code from the tester and pasted into JSFiddle, and the wildcard selector works there just fine (scroll down to see ሀ with the background color):

Any help is appreciated. Despite the large size .css file, keyboard performance seems fine.

thanks!

-Daniel

The reason it’s not working is that css selector div[id*='popup'] has lower specificity (0,1,1) than css selector div#popup (1,0,1).

So what is happening in the OSK is that the wildcard selector is being overridden by Keyman theming rules.

You could try a selector such as:

.tablet.ios div.kmw-key.kmw-key-default[id*='U_1200']

Two notes:

  • some of these custom CSS rules are probably going to need refresh with upcoming versions of Keyman when we revisit keyboard theming and styling, because they depend on internal, undocumented identifiers that are subject to change… I am hoping we can work with you to find a happy medium for end user theming vs keyboard layout theme.
  • popup keys will not be themed in current versions of Keyman for Android, because popups on Android are currently rendered as system elements, not web elements.
1 Like

Thanks for looking into it @Marc and providing the explanation. I’ll give your suggestion a try.

Shame about Android’s limitations. When the CSS styling works (iPhone, iPad) I think it looks terrific, and is very worth the effort.

I’m happy to help as I can where I can when it comes to the refresh. Mostly I think I could help by informing requirements via the use cases I come into, and then with testing.

Is the document model documented for the generated keyboards? I’m thinking of documentation like this KeymanWeb Layout Specifications , that would present the CSS nodes of the compiled keyboard.

1 Like

At this point, the DOM for generated keyboards is not documented. It contains a bunch of legacy hacks to support IE, Android Browser and old versions of mobile Safari. It’s also grown a bit messy over time, particularly with reference to IDs and class names. I’m hoping we can clean it up before we publish a DOM, as part of our push for better theming and customisability. The tricky bit is keyboards like yours which already have a lot of interaction with the existing DOM.

We want to move to using shadow DOM as well, which will allow us to greatly simplify the CSS and identifiers we use, avoiding conflicts with pages and more.

Current thinking here is that the best way forward will be:

  1. Abandon the existing DOM, class names, and identifiers.
    • For keyboards targeting older versions of Keyman, ignore their CSS rules. Yes, this leads to a loss of styling until those keyboards are updated, but prevents messy styling outcomes, and avoids the impossibility of trying to automatically migrate or back-compat handle complex CSS
      rules. The keyboards will continue to work.
    • For popular keyboards with significant CSS, the Keyman team would work with the keyboard authors during the alpha phase of the development so that, come release time, new keyboards would already be ready. This would also help ensure that our new design caters for the needs of the keyboard styling.
  2. Clean up and rebuild the OSK using modern web principles, shadow DOM.
  3. Document the new DOM structure, class names, identifiers, demarcations between general theming and per-keyboard styling, and limitations to use of CSS.

In terms of Android, we are planning to use web render for the popups in a future version.

1 Like

What would make the most sense is developing a Keyman CSS framework, and seperate positioning from visual appearance.

For visual styling, it would make sense to rely more on classes than element IDs. And avoiding specificity as much as possible. This would allow a more systemic approach to theming keyboards.

1 Like

For sure. There’s a lot of detail that we need to cover – size is one aspect of positioning, and there are requests for this to be configurable at the keyboard level. And @dyacob wants custom positioning as well :smile:

We’ll announce once we have a draft spec for this and look for your feedback!

Please add me too. I’d love to see it so that I can transition my CSS!
I also hope to style the android popups! I want all of my vowels (and vowel popups) to be distinctly styled.

1 Like

I thought I would report back that this approach worked, I modified it slightly to remove the .ios and specify both .phone and .tablet separately. It works for both .ios and .android:

.phone div.kmw-key.kmw-key-default[id*=‘U_1200’],
.tablet div.kmw-key.kmw-key-default[id*=‘U_1200’],

[later edit]

It’s worth mentioning that while the above works, I finalized with the form:

.phone div.kmw-key.kmw-key-default[id$=‘U_1200’],
.tablet div.kmw-key.kmw-key-default[id$=‘U_1200’],

which matches the key id, “U_1200” at the end of the string. This is safe since the full HTML element id uses the pattern layerID-keyID. In other cases, the end-of-string match is safer than the substring match. For example K_N is a substring of K_NUMLOCK . So a style set for K_N potentially gets applied to K_NUMLOCK depending on where in the CSS statements list they are specified. The collision is possible with *= but not with $= given the naming convention.

thanks!

1 Like

@Matthew_lee, will do!