Advanced [Re]styling of Mobile Keyboards with CSS

Hi all,
I watched the recent workshop videos with interest, and I’ve been tweaking the mobile versions of the Cameroon keyboard with CSS.


I have created a custom gradient “deadkey” style with the following code:

.kmw-key-deadkey{color:#0F0;background:linear-gradient(to right, darkgreen 33%, darkred 33% , darkred 66%, #aaaa00 66%);border:2px solid #FFFFFF;background-color:#ddd;}


Now I’m trying to remove the base character from the longpress popup to reduce the choices (often down to one). When I longpress “e”, i want to see “ə”, but not “e” (many other keyboard apps work this way). I figured that I would be able to call :first-of-type or :first-child in CSS, and mark it as invisible but the code that generates the keyboard elements is rather black-box.

1a) How can I select (and hide) the duplicate first key in the popup.
1b) If this is not currently possible, can this feature be added?

As Marten suggested in the workshop, I want to try highlighting vowels with a slightly different color, but:
1a) I’m already using the deadkey style, so I’ve run out of unused styles.
1b) I can’t seem to select a specific key in CSS, I was hoping to be able use #K_E, as this is the identifier of the key. Is it possible to do this yet?

Keyman Developer 10.0.1091

The custom CSS ‘feature’ (or wart) is a big hammer that can easily create problems for you and us in the future … yes, I’m really going to try here to dissuade you from taking this path! The intent of the CSS was really to allow differentiation of specific keys, probably with colour and/or font styling. But CSS allows a whole bunch of other things of course.

In particular, the customisation of the longpress behaviour and styling raises a bunch of problems:

  1. It won’t work in the Keyman for iOS and Keyman for Android apps because they implement longpress in native code, not in web.
  2. The changes won’t be forward-compatible with new versions of Keyman: we can and will make changes to the structure of the longpress menus, which will break your keyboard in unforeseen ways. We can’t afford to lock our CSS to the point where these types of tricks will be forward-compatible.
  3. The layout CSS is fairly finicky to get right, especially across older devices that still use Android Browser. We’ve done a heap of testing to get that right. Rotation and scaling are not as easy as they should be across devices. Are you willing to test against 200 devices?
  4. The code as written will impact every keyboard installed in Keyman, potentially even when your keyboard is not in use. (You need to update the selectors to include your keyboard id in the chain).
  5. You are trying to change the behaviour of the longpress menus. We won’t be testing against your changes when we make updates to Keyman, and so you may find that your keyboard suddenly stops working correctly.

In terms of gradient, it’ll probably mostly work but may cause performance problems on older Android devices – laggy keypresses etc. The old Android Browser on 4.x series devices struggled with gradients.

In other words, if you’d like to change the behaviour of the touch layout in the ways that you are attempting, it’d be much better to look at how we can implement these features in the apps themselves. We’d welcome suggestions in this forum or in the GitHub issue database. We are a small team – currently only 4 developers stretched across 6 platforms, so please understand that we cannot respond and implement suggestions as quickly as we want to.

Now, updating the styling is a dot point in our road map for version 11.0. Ideally, I would like to stop everyone from using the CSS misfeature until we have cleaned up the core CSS and removed a stack of legacy from it – and then define clear guidelines on how it should be used in a keyboard: the attributes supported and the selectors (layout and behavioural changes will never be supported in the CSS).

Huh, and now that I’ve posted my reply it seems you’ve edited out part of your post which means the picture is missing context? So not quite sure now what I was responding to :slight_smile:

You’re too fast. :slight_smile: Just after posting, I realized that “there be dragons” in Keyman’s CSS and removed the box resizing code. (It only seemed to work in the Chrome previews, not on the device) That’s what you mostly responded to…sorry.

You say: “The intent of the CSS was really to allow differentiation of specific keys, probably with colour and/or font styling.” So, is it already possible to style a specific key without restyling the whole class, or will that be a later feature? I really expected to be able to “Grab” the key with #K_E .

So, the option to remove the “base” key would need to be coded into Keyman and is not an after-market hack. That’s fine. It looks like the behaviour is defined here on line 600.

I’m wrapping the keyboard in an Android app and targeting android 5.0 and later for this keyboard, as some of the characters usually don’t work in 4.4. Even so, I believe I have a fallback color in case the gradient fails…I will test that.

Thanks @Matthew_Lee for spotting the dragons :slight_smile:

The key id is #layer-id, e.g. #default-K_E. Ideally you’ll prefix that with the name of your keyboard “foo” as well:

.kmw-keyboard-foo #default-K_E { color: red; }

Status report:

  1. kmw-keyboard-cameroon_azerty #default-K_E {color: yellow;) styles only Keyman Web, Including the Onscreen keyboard, and the Chrome previews (android/IOS), but not in native android Keyman. What do i use in place of kmw-keyboard-cameroon_keyboard to make it specific to my keyboard but inclusive of native android/iOS?
  2. #default-K_E {color: yellow;) works everywhere, but as you said, that’s a little broad.
  3. How do I restyle an individual native android/ios popup key (i.e. U_0259 which is a child of K_E on the default layer)? I have tried #default-K_E-U_0259, #kmw-popup-keys .kmw-key-U_0259 and about 8 other combinations.


Looking at my .js file, I see that the generated id is Keyboard_cameroon_azerty, while you suggested keyboard_cameroon_azerty. The keyboard name I gave it is Cameroon AZERTY.

keyboard_cameroon_azerty is the one that works in Keymanweb. Since Windows is less sensitive about caps than Android, Is this a capitalization normalization issue that doesn’t pass the keyboard id to KM native?

  1. Seems like the Android native app CSS may be overriding; @darcy_wong may be able to investigate this. Is the CSS rule correct? Your example is slightly wonky. .kmw-keyboard-cameroon_azerty #default-K_E {color: yellow; }
  2. Yep.
  3. You can’t currently restyle the native keys because they are native – they don’t consume the CSS that’s in the web layer. More wartiness I’m afraid.

Regarding the capitalisation, I don’t think that’s relevant to the issue. Capitalisation in JavaScript is identical in Windows and Android; it’s only in the filesystem that things differ. The capitalisation you are seeing is actually the name of the object constructor function which follows JavaScript naming principles of title-casing for objects (e.g. Window).