Skip to content

Graphical design guide

Yannick Warnier edited this page Mar 21, 2024 · 96 revisions

Technical guide

Chamilo 2.0 (and superior) change drastically in the way it handles web design. From a relatively static and sequential (and difficult to optimize) CSS loading process in Chamilo 1.* (mostly managed by the main/inc/lib/display.lib.php::display_header() method) to relying on Vue.js, Vuetify and Tailwind for styles in Chamilo 2.0+.

Vue.js

Vue is a javascript framework meant to simplify the building of reactive interfaces. It integrates progressively (by opposition with React and other similar libraries), meaning we don't have to rely on it entirely for every bit of our interface, which suits us best as Chamilo 2.0 is not a complete rewrite of Chamilo 1, but rather a big sequential improvement.

Vue is great to have the page work as semi-independent blocks of information. With Vue, we expect load times for many elements in Chamilo to be considerably reduced, as the whole page will not be reloaded after each action when the action only affect a piece of the page.

Primevue, Vuetify and Quasar

Primevue, Vuetify and Quasar are "components libraries" on top of Vue, that provide advanced interface components that can be re-used and extended through our interface. After some hesitation (so there might remain some traces of the others in the code) we are focusing on using Primevue.

Tailwind

Where Primevue offers mechanisms to improve the management of styles through default CSS packages, Tailwind is really an advanced CSS management library that allows us to mix and match pieces of CSS into a logical (although initially very confusing) structure.

Tailwind reduces the amount of CSS you have to write and, as such, makes it more maintainable. With Tailwind, you will practically never see pure CSS in your HTML. Each CSS style piece is named in a structured (and kind of magical) way and you only call these pieces from your HTML (or in our case, from our Vuetify components, most of the time).

The loading mechanism

To understand how the styles in Chamilo are generated, we'll take a user-facing approach first and dive into how these are generated.

When loading a Chamilo 2+ page, your will essentially find 2 CSS files:

  • /build/vue.css
  • /build/css/app.css
  • /build/css/[legacy].css

The first one is just the default Vue CSS. The second one, however, is generated through a complex process which we will analyse below. The third one(s) are legacy CSS files that have not yet been properly converted or that are very specific to one Chamilo tool

app.css

app.css is generated by Encore, using a configuration file located at /webpack.config.js (around line 15). It defines (around line 30) the list of CSS files that will have to be included in any Chamilo page. That's where we find the main one:

  .addStyleEntry('css/app', './assets/css/app.scss')

This /assets/css/app.scss is a working file that includes Tailwind packages (usually base, components and utilities), then goes on top of those Tailwind elements and define additional styles (like .btn-primary which will define the style of primary buttons).

These additional styles can include pure CSS, as this is where we will customize the Chamilo stylesheet to look as we intend Chamilo to look.

If you want to modify styles in a development context (and until we provide a better mechanism), edit /assets/css/app.scss, then run yarn run encore dev to regenerate app.css, reload your browser page and... voilà!

Primevue/Vuetify

Vuetify is not "compiled" by any process on the server. Vue will detect and manage the elements declared by Vuetify, and Vuetify is simply made available through a few lines in webpack.config.js. To use Vuetify (or Quasar), simply use the Vuetify (or Quasar) components inside your .vue files.

.vue files will be defined, mainly, in /assets/vue/views/ (although some are defined in parallel folders). They define pages layouts and blocks of information that will have a style and a behaviour defined by a combination of Vuetify and Vue.

Vue

Vue "simply" offers JS features. You would have to watch the video tutorials (see https://www.vuemastery.com/courses/intro-to-vue-3/intro-to-vue3) for Vue to make sure you understand it, because it is quite the opposite of sequential backend PHP code.

Vue is included into the loader stack through /assets/vue/main.js, loaded in webpack.config.js.

Design guide

Chamilo 2.0 is the first version of Chamilo of which the design has really been worked on as a framework, as opposed to common libraries used here and there. We expect the first stable version of Chamilo 2 to still have a lot of legacy parts that will still not integrate fully due to lack of resources (aren't we all hoping for a project that finances itself lavishly?), but we have a roadmap and expect to convert every layout to this new design as soon as possible.

8 point grid layout

We decided to use an 8 point grid layout, meaning we use multiples of 8px for pretty much anything. So as you design new interfaces, you should follow these rules:

  1. Use multiples of 8px when defining measurements, spacing, and positioning elements.
  2. When necessary use 4/6/12px to make more fine tuned adjustments.
  3. Whenever possible, make sure that objects line up, both vertically and horizontally.
  4. Align your bounding box to the grid, not the baseline of your text.

Because Tailwind mostly uses "rem" as distance units, it is important to note that, in many browsers, the default for 1rem = 16px, so our base unit for an 8 point grid is actually 0.5rem.

Fonts

We use DejaVu Sans for its permissive license (see https://commons.wikimedia.org/wiki/File:DejaVu_Sans_font.svg) and for its rounded shape that blends well into the general rounded design of Chamilo 2.

Icons & buttons

As design language, we are separating actions (add, edit, delete, move, configure, grade, export, import, save, enable, disable, ...) from links (to reporting pages, to tools, to specific areas of the interface) and descriptions (showing an indication of what an object is).

  • actions should be shown as text or icons, or both, on top of coloured buttons
  • links should be shown as simple icons, or text, or both
  • descriptions should be shown as a non-clickable icon. When icons are used to show tooltip documentation, these icons can be clicked/tapped to trigger the display of the tooltip

No non-action link should be shown on top o a button. Buttons are for actions only.

Buttons

Buttons should be colour-differenciated to allow users to quickly identify the type of action they represent.

We distinguish 4 categories of buttons that serve to act on resources (which match CRUD events):

  • creation related
  • reading related (special views, exports, etc)
  • updating related (other than creation/edition/destruction)
  • destruction related

Some additional buttons may not have to do with resources. For example, on a screen where you have to accept or reject a certain work flow, we can use similar colors as the ones used for creation and deletion, but these do not hold the same meaning. As such, they should bear different CSS classes.

The following table presents the visual differences between those and the classes to be used:

Category of action Action Description tailwind.config.js color Class
Create add green success ch-button-create
import green success ch-button-create
grade green success ch-button-create
save (even if during edition) green success ch-button-create
Read export blue primary ch-button-read
view (lists, details) blue primary ch-button-read
Update edit orange secondary ch-button-update
enable green success ch-button-update
move orange secondary ch-button-update
configure orange secondary ch-button-update
disable orange secondary ch-button-destroy
Delete delete red error ch-button-destroy
Accept accept green success ch-button-accept
Reject reject red error ch-button-reject
Cancel cancel gray gray (or gray-50) ch-button-cancel

Icons

All "non-legacy" icons are coming from the excellent (but somewhat limited in our case) Material Design Icons library. They are usually loaded either through a Vuetify component called <v-icon>(more), or through a legacy-hack method (so only for legacy code) called Display::getMdiIcon() (more).

We have already established a few standard uses for icons, and we believe establishing this standard list of icons here will simplify the process for designers and developers to implement new interfaces with a common look.

Classes

We have defined a few handy classes to give style to your icons, depending on context:

Class Purpose
ch-tool-icon Whenever using an icon to represent a type of object, an action or a state. This style uses the "primary" color defined in tailwind.config.js as the main icon color.
ch-tool-icon-disabled This is the same as ch-tool-icon, but when the icon represents an action or a state, and the action or state is considered disabled (for some reason), this style will ensure they appear grayed out.
ch-tool-icon-gradient Use only for bigger icons, for example on the course homepage to represent tools. This icon type uses a gradient from the primary to the primary-light color.
ch-tool-icon-button Use this style when the icon appears on top of an unstyled button. This renders an icon in the same color as the basic text (ch-text style from tailwind.config.js).

Default icons terminology

Because there are so many icons in the MDI library, and because we want to keep a certain cohesion between all parts of Chamilo (unlike in previous versions), some icons have been established to represent specific types of contents or actions. Here is a list of such icons.

The names given in the "icon name" column below are the names that will be given to Display::getMdiIcon() or, with an mdi- prefix, the names given to the <v-icon> component, in the icon attribute (e.g. <v-icon icon="mdi-pencil"/>).

The following tables are offered for convenience. While we will reasonably try to maintain those tables updated, we recommend using the dynamic script at /main/admin/list_icons.php (as admin on your portal) to get a visual list of all icons used, their respective PHP constant and the name of the icon in MDI.

First: common actions

A class exists to provide shortcuts to those icons: https://github.com/chamilo/chamilo-lms/blob/master/src/CoreBundle/Component/Utils/ActionIcon.php

You can call it through:

use Chamilo\CoreBundle\Component\Utils\ActionIcon;

The second column in the table below shows how to call the icon from your PHP code (Display::getMdiIcon(ActionIcon::[shortcut])).

Icon name Shortcut Action
plus-box ADD Add/Create a resource
pencil EDIT Edit
delete DELETE Delete
close-octagon-outline REJECT Reject
clipboard-check ACCEPT Accept
hammer-wrench CONFIGURE Configure
download DOWNLOAD Download
download-box DOWNLOAD_MULTIPLE Download multiple items
upload UPLOAD Upload
arrow-left-bold-box BACK Go back one page
account-multiple-plus SUBSCRIBE_GROUP_USERS_TO_RESOURCE Assign groups of users to some resource
cursor-move MOVE_DRAG_DROP Handle to move an element by drag & drop
chevron-left MOVE_LP_BACKWARD Move backward one page (learning paths)
chevron-right MOVE_LP_FORWARD Move forward one page (learning paths)
arrow-up-bold UP Move something up
arrow-down-bold DOWN Move something down or show some unfolded interface component
arrow-right-bold MOVE Move something (from one folder to another) or unfold some interface component
arrow-left-bold-circle-outline PREVIOUS Previous element
arrow-right-bold-circle-outline NEXT Next element
magnify-plus-outline PREVIEW_CONTENT Preview some content
archive-arrow-up IMPORT_ARCHIVE Import some kind of archive/packaged
folder-multiple-plus CREATE_CATEGORY Create a category
folder-plus CREATE_FOLDER Create a folder
alert ALERT Alert the user of something important/unexpected/undesired
checkbox-marked INFORM Inform of something completed
pencil-off EDIT_OFF Crossed pencil to show the inability to edit for the current user
eye VISIBLE Make invisible (by showing the current visible state)
eye-off INVISIBLE Make visible (by showing the current invisible state)
checkbox-multiple-blank UNPUBLISH_COURSE_TOOL Hide from course homepage (unpublish)
checkbox-multiple-blank-outline PUBLISH_COURSE_TOOL Show on course homepage
sync DISABLE_MULTIPLE_ATTEMPTS Disable multiple attempts (or show multiple attempts are currently enabled)
sync-circle ENABLE_MULTIPLE_ATTEMPTS Enable multiple attempts (or show multiple attempts are currently disabled)
fullscreen SET_DISPLAY_MODE_1 Display mode 1
fullscreen-exit SET_DISPLAY_MODE_2 Display mode 2
overscan SET_DISPLAY_MODE_3 Display mode 3
play-box-outline SET_DISPLAY_MODE_4 Display mode 4
fit-to-screen EXIT_FULLSCREEN Equivalent to fullscreen-exit?
bug-check ENABLE_DEBUG Enable debug
bug-outline DISABLE_DEBUG Disable debug
archive-arrow-down EXPORT_ARCHIVE Export in some type of archive/package
text-box-plus COPY_CONTENT Copy content
rocket-launch AUTOLAUNCH Enable/Disable auto-launch of some content
file-pdf-box EXPORT_PDF Export to PDF
file-delimited-outline EXPORT_CSV CSV export
microsoft-excel EXPORT_SPREADSHEET Spreadsheet export
microsoft-word EXPORT_DOC Document export
content-save SAVE_FORM Save the current form
send SEND_MESSAGE Send a message
paperclip-plus ADD_ATTACHMENT Add an attachment
dots-vertical VERTICAL_DOTS Three vertical dots to indicate the possibility to extend a menu/set of options
information INFORMATION Information icon - Get more info
account-key LOGIN_AS Login as
cloud-download TAKE_BACKUP Take backup
cloud-upload RESTORE_BACKUP Restore backup
printer PRINT Print
fast-forward-outline VIEW_DETAILS See details/View details (previously 2rightarrow.png)
broom RESET Clean/Reset
music-note-plus ADD_AUDIO Add audio
arrow-collapse-all COLLAPSE Collapse/Contract
arrow-expand-all EXPAND Expand
checkbox-marked-circle-plus-outline GRADE Give grades to work/learner
lock LOCK Lock
lock-open-variant UNLOCK Unlock
file-document-refresh REFRESH Refresh/Reload some resource
account-plus ADD_USER Add a user
format-color-fill FILL Fill (group with members, etc)
magnify SEARCH Search/find something, or search tool
comment-arrow-right-outline COMMENT Leave a comment
sort-alphabetical-ascending SORT_ALPHA Sort by alphabetical order (asc or desc)
sort-calendar-descending SORT_DATE Sort by date (asc or desc)
unfold-more-horizontal VIEW_MORE
unfold-less-horizontal VIEW_LESS
exit-run EXIT To unsubscribe from a course, a group, etc (as a user)
shield-edit-outline EDIT_BADGE For badges/skills edition

Second: Tools

These are the tools usually found on the course homepage. These are managed mostly through classes here: https://github.com/chamilo/chamilo-lms/tree/master/src/CoreBundle/Tool, so this list is relatively useless for development purposes (just instanciate the class and call $this->getIcon()).

A class exists to provide shortcuts to those icons: https://github.com/chamilo/chamilo-lms/blob/master/src/CoreBundle/Component/Utils/ToolIcon.php

You can call it through:

use Chamilo\CoreBundle\Component\Utils\ToolIcon;

The second column in the table below shows how to call the icon from your PHP code (Display::getMdiIcon(ToolIcon::[shortcut])).

Icon name Shortcut Tool
calendar-text AGENDA Agenda
bullhorn ANNOUNCEMENT Announcement
inbox-full ASSIGNMENT Assignment/Work/Student publication
av-timer ATTENDANCE Attendance
post-outline BLOG Blog
chat-processing CHAT Chat
apple-safari COURSE_DESCRIPTION Course description
upload COURSE_HOME Course homepage
progress-star COURSE_PROGRESS Course progress/Thematic advance
progress-check COURSE_PROGRESS_PLAN Course progress' lesson plan
progress-clock COURSE_PROGRESS_SCHEDULE Course progress' lesson plan schedule
book-open-page-variant COURSE Course tool
bookshelf DOCUMENT Documents
order-bool-ascending-variant QUIZ Exercise/Test
comment-quote FORUM Forum
alphabetical GLOSSARY Glossary
certificate GRADEBOOK Gradebook
account-group GROUP Group
map-marker-path LP Learning path
file-link LINK Link
wrench-cog MAINTENANCE Maintenance
account MEMBER Member (was: Users)
note NOTEBOOK Notebook
cog SETTINGS Settings
flash-outline SHORTCUT Shortcut
form-dropdown SURVEY Survey
image-text INTRO Tool intro
chart-box TRACKING Tracking/Reporting
video VIDEOCONFERENCE Videoconference
view-dashboard-edit WIKI Wiki
security SECURITY Security-related settings, security section
puzzle PLUGIN Plugins in general (the set of plugins) (inherited from the puzzle icon in 1.11 that suggests that plugins complete Chamilo)
library-shelves CAREER
school-outline PROMOTION
translate TRANSLATION
face-agent HELP
bug-check BUG_REPORT
inbox MESSAGE
account-box-outline SHARED_PROFILE
dropbox DROPBOX Dropbox tool

Third: Objects

These can be used anywhere in the interface (menu, course homepage to represent tools, table of contents of learning paths, action bars, etc). Although many of the "objects" replicate "tools", a forum tool has many threads and posts within, so the same icon that represents the forum tool (which inherently might contain many forums/fora) will not necessarily be the same as one forum object.

A class exists to provide shortcuts to those icons: https://github.com/chamilo/chamilo-lms/blob/master/src/CoreBundle/Component/Utils/ObjectIcon.php

You can call it through:

use Chamilo\CoreBundle\Component\Utils\ObjectIcon;

The second column in the table below shows how to call the icon from your PHP code (Display::getMdiIcon(ObjectIcon::[shortcut])).

Icon name Shortcut Object type/Resource
bookshelf DOCUMENT Documents
folder FOLDER Folder
order-bool-ascending-variant TEST Tests
file-link LINK Links
inbox-full ASSIGNMENT Assignments
comment-quote FORUM Forums
format-quote-open-outline FORUM_THREAD Forum thread
format-quote-open FORUM_POST Forum post
bookmark-multiple CHAPTER Chapter (e.g. in learning paths) / folder type (as opposed to document type)
certificate CERTIFICATE Gradebooks/Certificates
chart-box REPORT Tracking/Reporting/Statistics alternative
graph PREREQUISITE Prerequisites (e.g. in learning paths)
map-marker-path LP Learning paths
file-powerpoint PPT PowerPoint/Impress type document
arrow-down-bold PDF PDF format
star STAR Indicator that the resource belongs to a specific session, or is an admin user
star-outline STAR_EMPTY Something new
home HOME Homepage
book-open-page-variant COURSE Courses
google-classroom SESSION Sessions (not yet final choice of icon)
calendar-text AGENDA Calendar/Agenda
calendar-month AGENDA_EVENT Calendar event
calendar-star-outline AGENDA_PLATFORM_EVENT
calendar-filter AGENDA_USER_EVENT
calendar-end AGENDA_PLAN
calendar-week AGENDA_WEEK
account-multiple USER_LIST List of users
cogs ADMIN_SETTINGS Admin settings
cog SETTINGS Normal settings
bullhorn ANNOUNCEMENT Announcements
av-timer ATTENDANCE Attendances
apple-safari DESCRIPTION Course description
progress-upload COURSE_PROGRESS Course progress
alphabetical GLOSSARY Glossary
certificate GRADEBOOK
account-group GROUP Groups
account USER User account/Users tool
human-male-board TEACHER Teacher
form-dropdown SURVEY Survey
calendar-multiselect SURVEY_DOODLE Doodle-type survey
incognito ANONYMOUS Anonymous user/Make anonymous
video VIDEOCONFERENCE Videoconference
book-alphabet DICTIONARY Dictionary
shield-star BADGE Badges
file-tree-outline CATEGORY Categories (of anything)
cube-scan RESOURCE Resource (in the large sense, usually an object or set of objects that do not qualify as an existing object)
music-note AUDIO Audio file
paperclip ATTACHMENT Attachment
note-outline SINGLE_ELEMENT Single element (single squared white sheet as opposed to multiple)
note-multiple-outline MULTI_ELEMENT Multiple element (two squared white sheets as opposed to single one)
timetable TIME_REPORT A report that specifically deals with time
file-cad-box TEMPLATE A template file of some kind
card-account-details-outline VCARD
tire WHEEL Skills wheel
list-box-outline LIST
text-box-outline DEFAULT VIEW
pin PIN For special courses
ticket-confirmation TICKET
email EMAIL
cellphone PHONE
email-open-heart-outline INVITATION
email-heart-outline PENDING_INVITATION
package PROJECT
clipboard-list-outline WAITING_LIST
view-gallery-outline GALLERY
clipboard-check-outline RESULTS
arrow-decision SEQUENCE
map-marker MAP_MARKER

Fourth: States/Events/Alerts

States represent states of objects, visibilities, etc. This should not be used for buttons (actions) but for display (expressing the current state).

A class exists to provide shortcuts to those icons: https://github.com/chamilo/chamilo-lms/blob/master/src/CoreBundle/Component/Utils/StateIcon.php

You can call it through:

use Chamilo\CoreBundle\Component\Utils\StateIcon;

The second column in the table below shows how to call the icon from your PHP code (Display::getMdiIcon(StateIcon::[shortcut])).

Icon name Shortcut Object state
eye PUBLIC_VISIBILITY Public (used for courses visibility) (previously bullet-blue.png)
eye-outline OPEN_VISIBILITY Open (used for courses visibility) (previously bullet-green.png)
eye-off PRIVATE_VISIBILITY Private (used for courses visibility) / Invisible resource (previously bullet-orange.png)
eye-off-outline CLOSED_VISIBILITY Closed (used for courses visibility) (previously bullet-red.png)
eye-closed HIDDEN_VISIBILITY Hidden (used for courses visibility) (previously bullet-grey.png)
toggle-switch ACTIVE Active
toggle-switch-off INACTIVE Inactive
timer-alert-outline EXPIRED Expired (used for user accounts automatically expired)
alert-circle ERROR Error
alert WARNING Warning
check-circle COMPLETE Complete/Success
close-circle INCOMPLETE Incomplete/Failure
email-alert MAIL_NOTIFICATION Notification/Alert by mail
briefcase-eye SHARED_VISIBILITY
checkbox-marked-outline CHECKBOX_MARKED
checkbox-blank-outline BLANK
checkbox-intermediate CHECKBOX_INTERMEDIATE1
checkbox-intermediate-variant CHECKBOX_INTERMEDIATE2
checkbox-blank-off-outline CHECKBOX_INTERMEDIATE3
radiobox-marked RADIOBOX_MARKED
radiobox-blank RADIOBOX_BLANK
format-list-bulleted LIST_VIEW
format-list-text DETAILED_VIEW
filter-variant NESTED_VIEW
account-check ONLINE
account-off OFFLINE

Fifth: Presentation styles

View types for list of items.

Icon name View type
percent-box Percentage
format-list-text List of items

Converting legacy icons to material design icons

While converting Chamilo to use the new icons, there are 3 cases to take into account:

As a standard img tag in a Twig template

Convert

<img src="{{ 'edit.png'|icon(22) }}" title="{{ 'Edit'|get_lang }}"/>

to

{{ 'ActionIcon::EDIT'|mdi_icon_t(22,'ch-tool-icon','Edit') }}

(the 3 parameters to mdi_icon() are all optional).

Note: The mdi_icon_t filter (as opposed to mdi_icon without _t) has been designed to automatically pass the title argument through the translator function. If you want to show the title of a resource there, use mdi_icon, as you don't want that to be translated.

In an editor, you can use the following replace formula (with regexp enabled) to alliviate a little of the pain converting one syntax to the other:

Search: \<img src="\{\{\s*'(.*?)\.png'|icon\(22\)\s*\}\}"\/\>
Replace: {{ '$1'|mdi_icon(22) }}

You will still have to adapt to icon size and the real icon name in MDI, but at least it saves you from editing the lines one by one.

Template + Font Awesome to MDI

Convert

<a href="{{ something }}" class="btn ...">
  <i class="fa fa-plus" aria-hidden="true"></i>
</a>

to

<a href="{{ something }}" class="btn ...">
  {{ 'plus'|mdi_icon(64) }}
</a>

Search and replace syntax:

Search: \<i class="fa fa-(.*?)"(\s*aria-hidden="true")?\s*\>\<\/i\>
Replace: {{ '$1'|mdi_icon(22) }}
Inside PHP code, part of a link
Display::url(Display::return_icon('teacher_na.png', get_lang('Trainer view'), [], ICON_SIZE_MEDIUM), '#');

to

Display::url(Display::return_icon('human-male-board', 'ch-tool-icon-disabled', null, ICON_SIZE_MEDIUM, get_lang('Trainer view')),'#');

For action icons, a "translator" class is available to use a similar taxonomy to the one used in Chamilo 1.11 for the icon names: https://github.com/chamilo/chamilo-lms/blob/master/src/CoreBundle/Component/Utils/ActionIcon.php

Search and replace syntax:

Search: Display::return_icon\(\s*'(.*?)\.png',\s*(get_lang\(.*?\)?)(,\s*(.*?),\s*(.*?)\s*)?\)
Replace: Display::getMdiIcon('$1', 'ch-tool-icon', null, ICON_SIZE_MEDIUM, $2)

Notes: 1- make sure you vary the size depending on whether it's originally ICON_SIZE_SMALL(22) or ICON_SIZE_MEDIUM(32) 2- if the icon includes "_na", this usually means the icon must be in "disabled" mode, which translates in Chamilo to 'ch-tool-icon-disabled' (see the "Classes" section above)

Clone this wiki locally