Соглашения об именовании в UI Toolkit
Соглашения об именах в UI Toolkit
Если отладка — это процесс удаления ошибок из программного обеспечения, то программирование должно быть процессом их добавления. — Эдсгер В. Дейкстра, один из пионеров информатики
До сих пор руководство было посвящено стилю кода C#, но стоит также рассмотреть соглашения об именах для UI Toolkit, UXML и CSS. В UI Toolkit визуальные элементы и Unity Style Sheets (USS) запрашиваются по строковым идентификаторам, поэтому единый набор правил сокращает число ошибок и делает код понятнее.
Для визуальных элементов в UXML и классах таблиц стилей обычно рекомендуется методология «Блок — Элемент — Модификатор» (Block Element Modifier, BEM). BEM широко применяется в CSS и современной веб-разработке, на идеях которых основан UI Toolkit. По имени элемента в стиле BEM можно сразу понять, что он делает, где находится и как связан с окружающими элементами. Соглашение BEM включает три основных компонента: block-name__element-name--modifier-name
Рассмотрим пример: navbar-menu__shop-button--small Каждая часть имени может содержать латинские буквы, цифры и дефисы. Части соединяются двойным подчеркиванием __ или двойным дефисом --. Имя блока (block-name) обозначает высокоуровневый компонент, например меню навигации или панель характеристик персонажа, то есть самостоятельную и значимую часть интерфейса. Для универсальной кнопки, не относящейся к конкретному блоку, имя блока можно опустить: например, button--small.
Элемент element-name является дочерней частью блока и семантически с ним связан. Иными словами, контекст элемента задается блоком, и отдельно от него элемент не существует. В примере shop-button стиль показывает, что эта кнопка отличается от других кнопок блока navbar-menu: navbar-menu__shop-button.
Если новый элемент создает дочерние элементы в конструкторе, назначайте этим дочерним элементам соответствующие классы, например my-block__first-child и my-block__other-child. Модификатор обозначает вариант или состояние блока либо элемента: нажатую кнопку, выбранный и подсвеченный элемент текстового поля или, как в нашем примере, уменьшенный вариант кнопки магазина. Это позволяет поддерживать разные состояния без дублирования кода.
Еще несколько примеров именования по BEM: — menu__home-button — menu__shop-button — navbar-menu__shop-button--small
Имена классов BEM описывают сами себя: разработчикам проще понимать структуру и назначение компонентов, а четкая иерархия облегчает сопровождение и обновление стилей по мере роста проекта. В этих примерах части имени разделены дефисами — это стиль kebab-case, распространенный в CSS. Как и в других вопросах стиля, команда может выбрать подходящую схему, но лучше сделать это в начале проекта и затем соблюдать ее последовательно. Подробнее о соглашениях об именах в CSS читайте в этой статье и в документации UI Toolkit.
Рекомендации по именованию в UI Toolkit Ниже приведены рекомендации по эффективному именованию: — Делайте имена короткими, понятными и однозначными. Они должны быть лаконичными, но достаточно информативными, чтобы передавать назначение и роль элемента в интерфейсе.
— Не используйте в BEM-селекторах имена типов (Button, Label) или имена элементов (#my-button). Это избавляет от избыточности и возможной путаницы. Имена BEM должны описывать роль и состояние, а не тип элемента. — Избегайте имен и модификаторов, смысл которых может измениться. Например, пока цветовая схема не утверждена, используйте button--quit, а не button--red. Семантические имена остаются актуальными даже после изменения оформления.
— Распространяйте эти соглашения на графические ресурсы интерфейса UI Toolkit, например спрайты и текстуры. Единое именование в коде и ресурсах сохраняет понятные связи и улучшает организацию проекта. — Если элемент будет использоваться в других проектах, добавьте префикс к классам, чтобы избежать конфликтов с существующими пользовательскими именами. Пространства имен и префиксы предотвращают коллизии при интеграции с другими проектами и библиотеками. — В конструкторе вызывайте AddToClassList(), чтобы назначить экземплярам элемента нужные классы USS. Классы добавляются при создании элемента, поэтому соответствующие стили применяются сразу, а код интерфейса остается последовательным и понятным.
UI Toolkit naming conventions
If debugging is the process of removing software bugs, then programming must be the process of putting them in. — Edsger W. Dijkstra, computer science pioneer
While our guide so far has focused on C# code style, we also want to touch upon naming conventions for using UI Toolkit and working with UXML and CSS. With UI Toolkit you’ll need to query the visual elements and Unity Style Sheets (USS) using a string identifier, so using a defined set of standards will lead overall to fewer errors and more readable code. We generally recommend the Block Element Modifier (BEM) naming convention for your visual elements in the UXML and Style Sheets classes. BEM is widely used in the context of CSS and modern web development that is the inspiration for UI Toolkit. At a glance, an element’s BEM-style name can tell you what it does, where it appears, and how it relates to other elements around it. BEM uses three main components in the following convention: block-name__element-name--modifier-name
Here’s an example: navbar-menu__shop-button--small Each name part may consist of Latin letters, digits, and dashes. Also note that each name part is joined together with either a double underscore __ or a double dash --. The block name (block-name) represents a high level-compontent, like a navigation menu or character stats – a distinct and meaningful UI component in your layout. In the case of a generic button that is not specific to any particular block, that can simply be left out, e.g., button--small. The element element-name is a child or part of a block and therefore, semantically tied to its block. In other words, elements rely on the block for their context and cannot exist without it. So, in the case of the shop-button example, its style indicates that it’s different from other buttons belonging to the navbar-menu block (e.g., shop-button in navbar-menu__shopbutton). If your new element instantiates child elements in its constructor, assign the relevant classes to the children. For example, my-block__first-child, my-block__other-child. Finally, the modifier indicates a variation or state of a block or element. That could be when a button is pressed, a textbox item is selected and highlighted or in our example when it’s a small variant of the shop button. This makes it easy to adapt to different scenarios without duplicating code. Here are some more examples of BEM naming: —
menu__home-button
menu__shop-button
navbar-menu__shop-button--small
BEM class names are self-descriptive, making it easier for developers to understand the structure and purpose of components and making a clear hierarchy helps manage and update styles as projects grow. These examples use hyphen delimiting (aka Kebab case), which is common for CSS naming. Like with our other general guidelines, teams can decide which naming scheme works best for them, but should aim to choose early in the project and stay consistent later on. Read more about CSS naming conventions in this article, as well as in the UI Toolkit documentation.
Tips for naming conventions in UI Toolkit Here are some guidelines for effective naming: —
Keep names short and clear (unambiguous). It’s important to ensure that names are concise yet descriptive enough to convey their purpose and role within the UI.
Avoid using type names (Button, Label) or element names (#my-button) in your BEM selectors. This avoids redundancy and potential confusion. BEM names should represent their roles and states, not their types.
Avoid names/modifiers that can change (e.g., use “button–quit” instead of “button– red” when the color scheme is not yet final). Use semantic naming rather than presentational naming, which ensures names remain relevant even if styling details change.
Extend these conventions to art assets, like sprites and textures associated with the UI Toolkit interface. Consistency in naming between code and assets helps maintain a clear relationship and better organization throughout the project.
If you use the element in other projects, consider prefixing your classes to avoid conflicts with existing user class names. Namespacing or prefixing can prevent clashes when integrating with other projects or libraries.
Use AddToClassList() in the constructor to add the relevant USS classes to your element instances. This method ensures that the appropriate styles are applied by adding the necessary classes at the time of element instantiation, maintaining consistency and clarity in your UI code.