164 lines
8.5 KiB
ReStructuredText
164 lines
8.5 KiB
ReStructuredText
#######################
|
|
Styling in edx-platform
|
|
#######################
|
|
|
|
Over time, our Sass styling has become a little convoluted, with three major
|
|
reworkings often leading to confusion when a developer needs to style in
|
|
multiple locations across edx-platform. The main endeavors were v1, v2 (or
|
|
pattern library) and Bootstrap. We are trying to move away from using v2, as the
|
|
pattern library is deprecated, but there may still be locations in the code that
|
|
reference those styles (please remove them as you see fit).
|
|
|
|
Our platform uses a system of Sass partials that combine to compile into a
|
|
single large css file to be rendered on the page. From the Sass docs:
|
|
|
|
You can create partial Sass files that contain little snippets of CSS
|
|
that you can include in other Sass files. This is a great way to
|
|
modularize your CSS and help keep things easier to maintain. A partial
|
|
is simply a Sass file named with a leading underscore. You might name it
|
|
something like _partial.scss. The underscore lets Sass know that the
|
|
file is only a partial file and that it should not be generated into a
|
|
CSS file. Sass partials are used with the ``@import`` directive.
|
|
|
|
This structure allows us to break up our styling into small pieces, making
|
|
readability and maintenance easier, while often at the expense of structural
|
|
complexity as a code base grows. Here is an example, directly from edx-platform,
|
|
for how the partials flow to a single scss file that compiles into CSS for the
|
|
page to use. This is a page that uses v1 styling.
|
|
|
|
.. figure:: v1_sass_pipeline.webp
|
|
:alt: Sass Compilation for v1 CSS
|
|
|
|
Sass Compilation for v1 CSS
|
|
|
|
Note that this only shows an example, there are far more partials that come
|
|
together to make the ``lms-main-v1.css`` final file.
|
|
|
|
As you can see, the ``lms-main-v1.scss`` file does not have a leading
|
|
underscore, telling the compilation to turn that scss file into an actual css
|
|
file to be rendered on the page. If you were to use the Chrome Inspector tool
|
|
and look at the styling, you will see that there is one unified ``lms-
|
|
main-v1.css`` file that contains all the element styles.
|
|
|
|
The ``lms-main-v1.scss`` file uses the ``@import`` statement to pull in the
|
|
``_build- base-v1.scss`` and ``build-lms-v1.scss`` files which in turn import
|
|
more partials down the road. It is critical to recognize that this tree works in
|
|
a depth-first, first-come-first-serve manner. That means that styles that are
|
|
imported early in the process cannot reference Sass variables imported later in
|
|
the process (ie: ``bootstrap/variables`` cannot reference variables from
|
|
``shared/header``).
|
|
|
|
This diagram describes the process for the **v1 styles**, and there is a similar
|
|
setup for ``lms-main-v2.scss`` as well as ``bootstrap/lms-main.scss``. Each
|
|
individual HTML page on the edx-platform specifies which of the three that page
|
|
wants to use for styling. Please note that as an organization, we are slowly
|
|
trying to 1) move everything over to the bootstrap/lms-main.scss file and 2)
|
|
deprecate and stop using any v2 files. ``lms-main-v1.scss`` can still be used,
|
|
but a migration over to ``bootstrap/lms-main.scss``, and a migration of any
|
|
relevant partials from the v1 structure, would be a valuable endeavor.
|
|
|
|
Please note that as you add partials, make sure that they are not already being
|
|
imported in another file (ie: you add a node to the tree above that already
|
|
exists on the tree).
|
|
|
|
What theming does, and how to do it
|
|
***********************************
|
|
|
|
By thinking about the styling as a tree, theming becomes a lot simpler. All
|
|
theming means is that you can override one of the partials above by matching
|
|
the exact path in the ``edx-platform/themes`` directory. So, for example, to
|
|
override the shared header file (located at ``lms/static/sass/shared/_header``),
|
|
you would simply go into the ``edx-platform/themes/[theme you want to
|
|
override]/lms/static/shared`` folder and add a _header.scss file. When django
|
|
compiles the assets, it will use this file as a replacement to the main
|
|
edx-platform implementation.
|
|
|
|
If you look at the actual code base, you will see that we have a standard of
|
|
using the partials directory for these overrides files. This keeps the specific
|
|
components isolated from the core styling to reduce errors when people override
|
|
files and forget to import other files that are needed elsewhere on the site.
|
|
This is a good practice that future development should adhere to.
|
|
|
|
Final Note: When dealing with front end changes, it is a good idea to also check
|
|
the edx-themes repo, that works exactly like our themes folder, but also
|
|
includes html templates that can further confuse things.
|
|
|
|
Bootstrap and edx-platform
|
|
**************************
|
|
|
|
In a month and a half endeavor in the Fall, Andy and I worked on integrating
|
|
Bootstrap into the platform for three main reasons.
|
|
|
|
1. **To unify our styling:** By specifying colors and variables that can be used
|
|
universally, reducing the '50 shades of grey' issue and inconsistencies in the
|
|
ways that we style components.
|
|
|
|
2. **To add a widely used component library:** Bootstrap has a robust community
|
|
of developers that contribute to their open source component library, allowing
|
|
for easier prototyping and create of front end experiences.
|
|
|
|
3. **To simplify theming:** Since we now have a single unified source of truth
|
|
for our variables, openedx instances and alternative themes can simply override
|
|
those files to customly style their sites.
|
|
|
|
Relating to the above styling conversation, we have pulled in the entire
|
|
bootstrap styling library into ``lms-main.scss``, but only partially pulled it
|
|
into the v1 and v2 implementations due to naming conflicts. For example, we
|
|
could not pull in the bootstrap modal, due to conflicts with our own modal
|
|
styling (both use the generic ``.modal`` class). We were, however, able **to
|
|
pull in the entire bootstrap javascript file**, since that file overrides jQuery
|
|
in ways that our current application does not (meaning no conflicts).
|
|
|
|
Therefore, any pages that use lms-main.scss can use any bootstrap component out
|
|
of the box. **To use bootstrap components in older, v1, v2 pages** we have to
|
|
manually specify the exact Sass partial from the ``edx-
|
|
platform/node_modules/bootstrap`` that we want. For example, to add an alert to
|
|
a v1 page, you would add to ``base/build`` the partial ``bootstrap/scss/alert``.
|
|
Steps outlined below.
|
|
|
|
1. Determine from the ``node_modules/bootstrap/scss`` directory which component
|
|
you want to import.
|
|
|
|
2. Add that import (i.e: ``bootstrap/scss/alert``) somewhere in the Sass tree,
|
|
most likely to ``base/build.scss``
|
|
|
|
3. NOTE: Run ``paver compile_sass`` to make sure it works, if not, there is
|
|
likely a bootstrap mixin that you are missing. If so, search for the mixin in
|
|
``node_modules/bootstrap/scss/mixins`` and import it (i.e:
|
|
``bootstrap/scss/mixins/alert``)
|
|
|
|
4. You are done. Add the component using HTML or Javascript. Use the Bootstrap
|
|
Component Docs for examples.
|
|
|
|
FAQ
|
|
***
|
|
|
|
I want to add a new scss file for a feature on a particular page, how do I add it?
|
|
##################################################################################
|
|
|
|
First, you want to check which root file the page uses, whether it is
|
|
lms-main-v1, lms-main-v2 or lms-main. Then, go to that file and trace down the
|
|
tree to find a good spot for the new scss file to live. So, for example, if you
|
|
are adding an LMS feature and the page uses lms-main-v1, you can trace down lms-
|
|
main-v1 > _build_lms_v1 and see that there are plenty of standalone imports that
|
|
look like features. Simply add your file to the lms/static/sass directory in a
|
|
similar manner and add it as an @import to that page.
|
|
|
|
Why isn't my bootstrap component styling like in the bootstrap docs?
|
|
####################################################################
|
|
|
|
In any pages that use the lms-main.css compiled file, the bootstrap component
|
|
will render. This case only arises when we are working with a legacy v1 or v2
|
|
page. As outlined earlier in this document, we cannot import the entire
|
|
bootstrap repository due to conflicts with old styling. For v1 and v2, we are
|
|
gradually pulling in styles for components, so this must mean that you are
|
|
building a component that has not yet been used in the LMS/Studio.
|
|
|
|
To add the styles, you first need to find them in the bootstrap package. To do
|
|
so, search at edx-platform/node_modules/bootstrap/scss for the file that you
|
|
need. Then add this to the v1 or v2 tree, most likely to the build/base.scss
|
|
file. Note that you may hit issues with mixins when you try to compile the SASS.
|
|
In this case, check the edx-platform/node_modules/bootstrap/scss/mixins folder
|
|
and import that into the lms or studio before trying to import the component
|
|
styling.
|