
En septembre, nous avons publié le thème sombre de l'application officielle VK pour iOS, et il y a une semaine, la sortie a également eu lieu sur Android. Derrière ce lancement se trouve un excellent travail conjoint des développeurs et des concepteurs. Ensemble, nous avons non seulement fait basculer VK du côté obscur, mais nous avons également changé sérieusement l'approche du travail avec les couleurs dans nos interfaces, simplifiant leur choix et réduisant la probabilité d'erreurs et engendrant des styles inutiles.
Mon nom est Mikhail Likhachev, je suis l'un des principaux concepteurs de VK. Je vais vous dire comment une petite équipe a adapté 300 écrans et systématisé toutes les couleurs qui existent dans les applications mobiles - pour cela, nous les avons synchronisées entre les plates-formes et regroupons le travail avec elles dans un système de conception unique avec des jetons. Je partagerai mes impressions sur la façon dont nous vivons maintenant avec cela et si le processus de conception est devenu plus compliqué.
Pourquoi avons-nous besoin d'un thème sombre
Un contraste réduit et un fond sombre aident à utiliser l'application en basse lumière, sans forcer les yeux. Google confirme que lors de l'utilisation d'un thème sombre, les appareils dotés d'écrans AMOLED durent plus longtemps sans se recharger. Et beaucoup de gens aiment juste la couleur noire ou veulent un nouveau thème de design (tout en étant bien sûr sans refonte).
Maintenant, le thème sombre est mis en œuvre non seulement dans les applications populaires, mais aussi dans les systèmes d'exploitation macOS, tvOS, dans les lanceurs Android. Et son apparition sur tous les appareils iOS et Android ne tardera certainement pas à venir.
Pour nous, c'était aussi la mise en œuvre d'une fonction tant attendue - les utilisateurs posaient plus souvent des questions sur un sujet sombre. Il s'est avéré être très demandé - maintenant plus de 20% du public utilise régulièrement un thème sombre sur iOS et Android.
Système de couleur
Avant de créer un thème sombre, nous devions réorganiser la palette de couleurs de notre application. L'objectif était le suivant: à la fois dans le code et dans la conception, il ne devrait pas y avoir de couleurs qui ne soient pas incluses dans la palette fixe. Pour un petit ensemble de couleurs, il sera plus facile de faire correspondre le thème sombre.
Lorsque nous avons vérifié l'ensemble de l'application et collecté toutes les couleurs, nous avions plus de 200 valeurs HEX uniques. Depuis la sortie de la première version de VK App sur iOS, plus de 6 ans se sont écoulés, l'application a subi plusieurs remaniements. Quelque part jusqu'à présent, les écrans non mis à jour ont été conservés, et quelque part il y a eu des situations où la même couleur avait une valeur qui diffère de manière extrêmement insignifiante. Par exemple, une seule couleur dans HSB peut avoir différentes valeurs HEX dans Photoshop et Sketch.
Notre application est très large. Nous pouvons dire que ce sont plusieurs applications en une: nouvelles, musique, vidéo, histoires, émissions, tout un messager et de nombreuses autres sections et services tout aussi importants. Nous avons compté 300 à 400 écrans uniques, chacun ayant plusieurs états. Les nouvelles à elles seules ont plusieurs types d'affichage des enregistrements et plus de 15 types de documents joints. Pour une telle application, un système plus complexe est nécessaire où les couleurs seraient décomposées par niveaux de contraste afin qu'il serait plus facile de les sélectionner non seulement pour un thème sombre, mais aussi pour de nouveaux contrôles.
En termes d'organisation du système de couleurs, nous avons le plus apprécié l' approche de Material Design . Nous avons préparé trois palettes étendues dans un système similaire: gris, gris froid et bleu. Dans le même temps, nous avons divisé les couleurs par niveaux de contraste avec des valeurs conditionnelles de 0 à 1000, où 0 est le plus clair et 1000 est le plus sombre. Ces numéros sont devenus des identificateurs de couleurs avec le nom de la palette - Gris 100, Bleu 300 et ainsi de suite.

Lors du choix des couleurs, le modèle de couleur HSB est utile. Dans ce document, Hue est la tonalité de couleur, la saturation est la saturation et la luminosité est la luminosité. La teinte varie de 0 à 360 °, et nous utilisons une valeur fixe de 212 ° dans les interfaces comme tonalité de couleur de notre marque. La saturation et la luminosité sont définies de 0 à 100%.
Comme nous divisons la palette de gris en 10 nuances principales, dans Luminosité, nous utilisons un pas de 10%. Ensuite, nous mélangeons la couleur bleue avec la saturation le long d'une petite courbe, tout en ajustant les valeurs de luminosité pour préserver la gradation de contraste dont nous avons besoin.
De la même manière, nous avons ramassé les palettes froides de gris et de bleu. Le gris froid est utilisé dans les endroits où une teinte plus saturée est nécessaire pour se combiner avec le bleu, et plusieurs couleurs bleues sont nécessaires pour les accents, les différents boutons, le texte et les liens.

Nous utilisons le gris le plus souvent pour une grande variété d'éléments: arrière-plans, substrats, séparateurs, icônes, textes de différents niveaux. La plupart des nuances de gris que nous avions déjà sélectionnées avec une différence de contraste similaire, et lors de la mise à jour de la palette, nous avons légèrement décalé les valeurs de plusieurs couleurs pour correspondre à la nouvelle logique. Et a également complété la partie manquante des couleurs dans le spectre sombre afin de les utiliser pour un thème sombre.
Absolument toutes les couleurs utilisées dans l'application ont été ajoutées à la palette, y compris celles représentant différents événements dans les notifications, et même les couleurs du mode de dessin graffiti dans les histoires. Tout est devenu beaucoup plus transparent: désormais toutes les couleurs de l'application sont rassemblées en un seul endroit. Et lorsque vous ajoutez une nouvelle couleur pour un cas particulier, vous devez réfléchir soigneusement et vérifier si la couleur est appropriée par rapport aux couleurs existantes.
Après avoir préparé la palette prédéfinie, elle a dû être appliquée dans l'application, remplaçant plus de 200 valeurs HEX disponibles par un nouvel ensemble de plus de 50. Et mettez toutes ces couleurs dans un fichier sous la forme de variables statiques, où chaque couleur de la palette a un nom unique.
Nos développeurs de l'équipe infrastructure sur iOS et Android ont repris cela. Les gars ont préparé un algorithme qui remplace la couleur par la plus proche de la nouvelle palette, ce qui a considérablement accéléré le processus. Ensuite, nous avons vérifié tous les écrans avec des testeurs afin que la mauvaise couleur ne soit appliquée nulle part, et finalement nous avons repris le thème sombre.
Couleurs assorties dans un thème sombre
Nous avons commencé à essayer les couleurs du thème sombre sur les dispositions des écrans principaux afin de déterminer les principales nuances utilisées. Pour l'arrière-plan, nous utilisons le gris 900 - la couleur est un ton plus claire que le noir pour réduire le contraste entre l'arrière-plan et le texte. Pour la même raison, le texte a été choisi non pas Blanc, mais Gris 100.
Toutes les couleurs principales du thème sombre ont été identifiées par la même gradation qu'à la lumière. Après avoir mis les styles les uns après les autres en luminosité, nous avons sélectionné les valeurs appropriées, en les inversant et en décalant le niveau de contraste d'une tonalité. Nous avons ensuite testé les couleurs sur les mises en page, en nous assurant que tous les éléments conservaient la lisibilité.

Tableau des couleurs primaires utilisées
Dans le thème sombre, nous avons utilisé moins de couleurs: le chapeau bleu et les boutons bleus sont devenus monochromes, la gamme de nuances de gris utilisées s'est rétrécie et la palette de gris froid s'est transformée en un gris ordinaire, maintenant le contraste. Les éléments d'accent sont restés bleus - pour un thème sombre, une teinte plus claire et moins saturée a été choisie.

Il y avait aussi des problèmes, comme les fenêtres modales et les cartes. La gradation sous eux ne voulait pas être inversée en blanc, et sans mesures supplémentaires dans un thème sombre, l'arrière-plan habituel du contenu fusionnerait avec l'environnement. Pour éviter cela, pour les cartes modales, nous avons sélectionné l'arrière-plan un ton plus clair que d'habitude, et avons également ajouté un trait (jusqu'à présent uniquement sur Android) pour mieux les séparer du calque inférieur.
Ces exemples ont montré que nous avons besoin d'un système plus flexible lors de la mise en œuvre d'un sujet sombre.
Implémentation technique
Après avoir choisi les couleurs appropriées pour le thème sombre sur les maquettes, nous avons commencé à transférer cette question dans le code.
Comme nous l'avons vu sur les maquettes, introduire simplement la correspondance des couleurs d'un thème clair dans un thème sombre n'est pas notre option. Le blanc n'est pas toujours remplacé par le noir: les éléments de même couleur dans un thème clair peuvent avoir des couleurs différentes dans un thème sombre. Nous avions besoin d'un contrôle précis sur la façon dont chaque élément ou groupe de styles communs est repeint dans un thème sombre. Les éléments doivent changer de couleur conformément à la signification inscrite dans le nom de la variable.
Nous avons décidé de l'approche suivante, où le jeton est le nom unique d'un élément ou d'un groupe d'éléments (par exemple, background_content), et sa valeur ne peut être qu'une couleur d'une palette fixe (par exemple, le blanc). Nous avons créé un schéma au format JSON, à l'intérieur duquel tous les jetons sont écrits avec leurs valeurs dans chaque rubrique.
Un tel schéma est très similaire à un fichier CSS avec des identifiants d'éléments et leurs styles, mais au format JSON.

À quoi ressemble le schéma avec les jetons background_content et text_primary?
Tout ce que nous avons est disponible sur GitHub:
- une palette avec toutes les couleurs et leurs noms uniques;
- schéma avec tous les jetons et leurs valeurs dans les sujets clairs et sombres.
À partir du schéma JSON, les développeurs sur toutes les plateformes génèrent du code au format dont ils ont besoin. Vous pouvez lire à ce sujet des exemples de code sur iOS sur les diapositives d' Anton Spivak tirées de son discours à CodeFest. Le rapport sur la mise en œuvre d'Android du discours d'Arseniy Vasiliev à AppConf peut être consulté ici .
Rappelons que nous avons décidé de créer un système strict où vous pouvez spécifier la couleur uniquement à partir de la palette interne, c'est-à-dire que vous ne pouvez pas enregistrer un code couleur HEX arbitraire dans la valeur du jeton. Le paramètre alpha peut être ajouté à la valeur du jeton pour indiquer une transparence de couleur supplémentaire. Nous prévoyons d'utiliser ce paramètre pour ajouter un état désactivé et un état lorsque vous touchez les commandes, afin de ne pas ajouter les mêmes couleurs avec une transparence différente à la palette.
À l'heure actuelle, le système compte déjà plus de 150 jetons. Il existe des variables globales, ainsi que des styles complètement peints de chaque contrôle, ainsi que des cas uniques qui ne se prêteraient pas à une combinaison plus logique, par exemple, les styles de bulles des messages.

Exemples de jetons couramment utilisés
Un point important est qu'il est nécessaire de nommer clairement et brièvement les jetons afin de les trouver facilement et rapidement. Le principe de dénomination a été choisi comme suit - du plus grand au plus petit. Par cette logique, dans les styles globaux, le type général est d'abord indiqué, et les composants, dans l'ordre, ont un nom, un état et à la fin un élément repeint spécifique. Si possible, le jeton doit être universel - refléter le type et la signification sémantique, et non son emplacement et son contenu dans un cas particulier.
Poursuivre le travail avec le circuit
Sketch and Zeplin
L'étape suivante: vous devez fournir aux développeurs des informations compréhensibles sur les jetons utilisés dans les mises en page. Pour ce faire, nous avons visualisé le jeton sous la forme d'un symbole, où en plus du nom, il y a un aperçu de la couleur utilisée dans les thèmes sombres et clairs, ainsi que les noms des couleurs de la palette.
Nous avons généré de tels jetons sous forme de symboles après avoir constitué la majeure partie du circuit, et il y avait déjà beaucoup de jetons. Afin de ne pas les composer manuellement, nous avons préparé un petit plug-in qui a extrait la version actuelle du schéma JSON et a généré des jetons à partir d'eux sous la forme de symboles à partir du modèle, en remplaçant les couleurs des styles généraux de la bibliothèque de couleurs. En utilisant le même plugin, nous générons une mise à jour de la bibliothèque: de nouveaux jetons sont ajoutés et les valeurs des jetons existants sont mises à jour. Le symbole de la bibliothèque est mis à jour dans toutes les présentations où il est utilisé.

Voici à quoi le jeton ressemble à un symbole
Nous ajoutons de tels jetons à côté des mises en page et envoyons tout ensemble à Zeplin. S'il n'est pas immédiatement clair par son nom ou si vous devez clarifier à quel élément les jetons appartiennent, ajoutez une description et divisez les jetons en sections, décrivant des éléments spécifiques. En utilisant le plugin Sketch Runner pour rechercher rapidement les noms de symboles, nous avons obtenu notre constructeur de description de thème sombre sous la forme d'annotations de disposition.

Ajout d'une description des jetons utilisés
Nous n'avons pas trouvé de solution plus native, simple et visuelle sur la façon d'intégrer des jetons dans des mises en page avec un envoi ultérieur à Zeplin. Bien que Zeplin puisse nommer des couleurs uniques, dans notre schéma, une couleur peut être utilisée dans plusieurs jetons à la fois.
Au lieu de dessiner une version sombre pour chacun des centaines d'écrans, nous décrivons simplement tout sous forme de jetons, ce qui fait gagner du temps aux concepteurs. Toutes les valeurs de jeton disponibles pour les composants ont déjà été testées, et il vous suffit de remplacer les bonnes. Le seul point de vérité est le kit d'interface utilisateur - vous y trouverez non seulement l'état actuel du composant, mais aussi ses jetons utilisés.
Des erreurs dans la mise en œuvre du thème sombre peuvent déjà être trouvées lors de la phase de test lors de la vérification des captures d'écran. Les testeurs eux-mêmes peuvent remarquer une couleur clairement fausse et demander de l'aide au concepteur - pour corriger un défaut, vous n'avez besoin que du nom du jeton correct.
Mises à jour du schéma
Lorsque vous devez mettre à jour le schéma, remplacer les valeurs des jetons existants ou en créer de nouveaux, il vous suffit de modifier le fichier JSON. Pour ce faire, nous récupérons la version actuelle du schéma et apportons des modifications dans un éditeur de texte, sans oublier d'ajouter des valeurs pour tous les sujets lors de l'ajout d'un jeton. Il est prévu de créer une application pour elle-même qui vous permette de modifier le schéma de manière plus simple, mais pour l'instant cela suffit.
Après avoir préparé le schéma mis à jour, nous envoyons la demande d'extraction à GitHub (demande de modification du fichier), qui est vérifiée et approuvée par les développeurs. Après avoir fusionné les modifications, les développeurs doivent resserrer la mise à jour de la bibliothèque d'interface utilisateur, puis de nouvelles couleurs apparaîtront dans le prochain assemblage de développeurs dans 15 minutes.
Pour renommer ou supprimer des jetons dans le schéma, nous créons une mise à jour majeure en augmentant sa version dans GitHub. Cela signifie qu'une telle version ne pourra pas être appliquée automatiquement, et avant de mettre à jour la version de la bibliothèque d'interface utilisateur, les développeurs doivent prendre en charge toutes les modifications: mettre à jour les noms des jetons, et si le jeton supprimé a été utilisé quelque part, vous devez suivre le commentaire de la liste des modifications indiquant quel jeton est nécessaire utiliser à la place.
Nous pouvons publier de telles mises à jour lors de la refactorisation du schéma: lorsqu'il y a une compréhension de la meilleure façon de nommer les jetons, ou s'il s'avère combiner plusieurs jetons en un, tout en préservant la logique.
Les couleurs dans les applications iOS et Android sont presque identiques, donc le schéma de couleurs créé lorsque vous travaillez avec iOS convient à Android. S'il y avait des différences de plate-forme, vous pouvez toujours créer des jetons avec le suffixe de plate-forme.
En plus des applications natives, nous avons VKUI . Il s'agit d'un ensemble de composants React avec lesquels vous pouvez créer des interfaces qui ne se distinguent pas de nos applications. Nous utilisons VKUI pour créer des produits de test dans VK, ainsi que pour des écrans que nous aimerions contrôler depuis le serveur sans mettre à jour l'application. De plus, cette bibliothèque est utilisée pour créer des services VK Apps tiers.
VKUI est construit selon la même conception et avec le même ensemble de composants que les applications natives, donc l'application du schéma et la prise en charge d'un thème sombre ne nécessitaient pas de nouvelles dispositions. Pour nous, c'est une autre plate-forme que nous prenons en charge, seulement elle contient un commutateur entre iOS et Android.
Vous pouvez voir la mise en œuvre du système de conception VK sous la forme de composants React sur VKUI Styleguide . Et la chose la plus intéressante est que sur cette page, vous pouvez voir en direct les composants que nous utilisons avec la possibilité de changer de thème et de plate-forme.
Dans un avenir proche, nous mettrons à jour la documentation de VKUI et collecterons plus d'informations sur le travail de notre équipe de conception - il y aura beaucoup de choses intéressantes ️
Sujet séparé pour le messager
VK Me, qui n'est testé qu'au Kazakhstan jusqu'à présent, est un messager distinct avec la possibilité de s'enregistrer par numéro de téléphone. Dans ce document, nous avons non seulement facilité la fonctionnalité, ne laissant que la communication, mais également simplifié la conception.
Le chapeau dans le sujet clair est devenu blanc pour se concentrer sur la communication, et le bleu est devenu plus lumineux et plus saturé.

Le messager est basé sur le module de message de l'application principale, ce qui signifie qu'il utilise les mêmes composants et le même schéma pour décrire toutes les couleurs. Par exemple, pour repeindre l'en-tête et la recherche, il était nécessaire de remplacer les valeurs des jetons correspondants: header_background, header_tint, header_text, search_bar_background, search_bar_field_background search_bar_field_tint et autres.
D'une manière assez simple, nous avons pu repeindre l'ensemble de l'application en peu de temps, créant un nouveau thème de conception.
Travailler avec des graphiques
L'ensemble des icônes utilisées dans les applications est coupé en blanc et peut être facilement repeint à l'aide d'un jeton du circuit.
Des difficultés sont apparues avec les icônes bicolores: les icônes qui se superposaient au dessus des avatars sous forme de badges et qui nécessitaient un trait blanc, étaient découpées en deux couleurs. Il ne serait pas facile de repeindre cela. Nous avons divisé ces icônes en deux couches, l'avant et l'arrière-plan, qui sont utilisées comme masque et découpent la forme nécessaire.

Android dispose également de graphiques à 9 patchs, qui sont utilisés, par exemple, pour dessiner des cartes avec des ombres. L'ombre en eux est noire et le remplissage de la carte est blanc. Afin de ne pas diviser les graphiques ici en deux couches, les développeurs ont utilisé le mode de fusion des couleurs Multiplier - de cette façon, l'ombre noire n'est pas repeinte et la couleur n'est appliquée qu'à la partie blanche des images, ce qui était nécessaire pour nous.
Résumé
Lors de la mise en œuvre d'un sujet sombre, nous avons sérieusement stimulé les processus, portant la relation entre la conception et le développement à un nouveau niveau.
Un schéma unique, qui intègre tout le travail avec les couleurs dans l'application, est devenu un outil puissant mais abordable pour les concepteurs et simplifie les futures mises à jour de conception. Le niveau de responsabilité et de sens dans la création de styles et l'ajout de couleurs a augmenté.
Lorsque des noms clairs reflétant le contraste des couleurs sont apparus, il est devenu beaucoup plus facile de naviguer avec eux qu'avec les valeurs HEX. Il en va de même pour les jetons - ils sont mémorisés en raison de leur signification, et l'adhésion à la logique des styles utilisés sur plusieurs plates-formes et applications devient une partie indispensable du processus.
Le processus prenait du temps non seulement pour les concepteurs, mais aussi pour les développeurs et les testeurs. Mais cela en valait la peine - le sujet sombre a recueilli des critiques positives des utilisateurs et les commentaires sur le «sujet sombre» qui se sont répandus dans VK et sont même allés au-delà ont réussi à devenir un mème.