badlydrawnrob / anki

Learn to code with Anki — flashcards and themes for all learning levels. Master your programming language of choice!
MIT License
719 stars 61 forks source link

Moving to GPS method #146

Open badlydrawnrob opened 1 month ago

badlydrawnrob commented 1 month ago

Which methods live on? Which methods die?

Great advice from helpful articles

Trialling out GPS, some old stuff from ECSS, and my idea: "Thema styles".

I'm not entirely convinced yet about GPS-style css, but I DO believe in minimalism and increasingly have a brutalist mindset. While it's nice to have a fancy UI, it isn't necessary, and it's a real bugger to maintain and update as the code complexity increases. CSS is definitely not one of the nicest languages to code in.

The general idea

For example, with ECSS you'd write a special .scoped-Class for each and every item. This is a big no-no in GPS and it advocates for simplifying the class names, using raw html elements to style, and reducing repetition. However, some naming conventions are necessary ...

What about <div>s when there's no relevant HTML element to use? It's quite helpful to have some visual indication when you're scanning the css document as to what component lives where. If you don't have a nested element such as .gl-Card header, and you've got two nested div > div that gives no information.

<!-- simple naming convention -->
<div class="split">
  <div class="split-left">
    ...
  </div>
</div>

<!-- ECSS naming convention -->
<div class="gl-Section">  <!-- If it's a global element GPS condones scoping as `.gl-`obal -->
  <div class="gl-Section_Left">
    ...
  </div>
</div>

The general idea with GPS is to scope things as .gl-obal, #page level, or section (nested under it's page). It aims to reduce bloat that BEM and ECSS bring with (some would say) unnecessary class names. The problems that seem to crop up when changing to this format are:

  1. If you have a fragment (like #answer) which is just for linking to, where does this live?
  2. Are there any instances where inheritance becomes a potential problem? (unique ECSS classes solved this problem)
  3. If templates are slightly different, how do we deal with these? (Missing! div#answer is in a different position)
  4. Is styling raw HTML elements always preferable to adding an explicit .class or not?
    • Design-systems will naturally have parent and child elements ... not all of them explicit as to their purpose as raw html
    • .gl-Form p seems a bit weak compared to more explicit .gl-Form_Error which is far more explicit ...
    • See here for an example of before and after: using a flat class style vs nested style.
    • I guess the GPS way is to just give it a singular class .gl-Form .error?
  5. Having to constantly create class names is a pain, but sometimes explicitness is preferable:
    • If not nested, gl-Card_KeyPoint tells me a lot about what it is and who its parent is.
    • I guess it's unlikely elements will be moved around, but you'd potentially lose some of their styling if so:
      • i.e: .gl-Card > p would break if you moved p inside a div. Perhaps this is just something you have to be aware of.
  6. How to avoid any inheritance issues rising from code order?[^1]
  7. Should placeholder elements, classes, or ids be discouraged?
    • For instance, a .gl-Wrapper class that hasn't been styled yet. Is it really needed?
  8. Do we prefer flat style css or nested?
    • .gl-Card { .wrapper { ... } } vs .gl-Card .wrapper
    • .gl-Card h1 code b seems a bit too nested for my tastes, but perhaps it's just habit.
  9. If we have a .nightmode class, should all override styles live together, or style in-place multiple times?
    • For example, have multiple instances of night mode where it's needed: .gl-Card { .nightmode & { ... } }?
    • The same goes for @media styles. They can add up pretty fast (see Print First CSS)
  10. Reusing templates is better, but sometimes this isn't possible.
    • Slight variations in templates mean they share .gl- styles except for very slight changes.
    • With ECSS we'd completely separate (and duplicate) those styles into two distinct css files.
    • Remember Elm Lang's lessons: just because something is similar does not mean it is the same!
  11. Another subtle example is our #demo page. It's serving two distinct templates but they're basically exactly the same:[^2]
    • At what point does a .gl- element become a distinct #page #section and vice-versa?
    • Should I be naming #demo a .gl-Demo rather than a distinct #page type?
    • Can #page elements be repeated or must they be unique?
  12. Another what-if in a similar vain is ... is it every OK to style a .gl- element under a #page level one?[^3]
    • You could style it in the global-element.less file like .gl-Element { #page & { ... } }
    • Or otherwise you could convert a .gl-Element to a #page #element but that's waaaaay overkill in my case.
    • Or, you could add a -variant class, such as .gl-Element-changed ...

TL;DR

One of the biggest upsides of using ECSS is isolation and descriptiveness. .gl-Card_KeyPoint-selected is very descriptive. You lose that a bit with GPS. So whatever you do, make rules concrete.

  1. Use decent HTML5 tags where possible to style content. Make them obvious and accessible.
    • section, header, aside, nav are descriptive enough, sort of.
    • p and ul feel a bit weaker, especially if it's a design system element (is it descriptive enough without a class?)
  2. If <div> is used, and it's a child of another div, consider naming them as parent and child somehow.
  3. Ideally you'd want to style as much as possible in your raw html /partials folder.
    • For our Anki cards, we really only have one style of heading, but that's inside a .gl-Card.
    • Are we ever going to use a h1 outside of this context? How much do we style in /partials?
    • To me .gl-Card is a component. I'm not sure it should live as the specimen file (basic h1 -> h6 styles)
  4. 144 — be consistent!

  5. When dealing with similar but not the same .gl-, #page, #section elements, WE NEED A PLAN!
  6. Unique #section elements should always be wrapped in a #page

[^1]: One example of this is <code> styling. We want to style the default, but it also needs styling in a few different occasions: Within a <header> element, inside <pre> tags (specifically with .sourceCode which is a Skylighting class), so on. For h1 code we want font-style: inherit but where does that code live? We're only really using headings inside of our .gl-Card but we might need header styles as regular headings at some point. Do we style the raw HTML or the .gl-Card header h1? And if we're placing "inherit" in our raw html styles (in /partials), will code inherit the styles from our .gl-Card headings too? I don't know! Test it out!

[^2]: Im not sure that GPS gives us definitive answers to these problems. It's kind of subjective in these cases.

[^3]: This is another area with nuance that we've got to be aware of. At what point do you split out a .global style into a different (but similar) global style? I think it's generally that a #section should be UNIQUE. But it might be similar to a global design component. Again, we don't worry about this with ECSS.