Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate CSS stylesheets #61

Closed
huyenltnguyen opened this issue Apr 10, 2024 · 5 comments · Fixed by #114
Closed

Consolidate CSS stylesheets #61

huyenltnguyen opened this issue Apr 10, 2024 · 5 comments · Fixed by #114
Assignees
Labels
status: PR in works Work in Progress (WIP) Issues.

Comments

@huyenltnguyen
Copy link
Member

huyenltnguyen commented Apr 10, 2024

This ticket is semi-related to freeCodeCamp/freeCodeCamp#52030.

In order to replace Bootstrap in /learn, we need to export a stylesheet from the component library to be used as the bootstrap.min.css replacement. However, the stylesheet situation in the component library itself needs to be sorted out, and this ticket is to track this work.

Current problem

The library currently has multiple stylesheets. Their purposes aren't clear, they have many similar CSS rules and some of the CSS rules don't match, which could cause styling issue if the import order changes.

The stylesheets are:

Observation:

  • Except for colors.css, the stylesheets overlap each other:
    • ui/src/base.css

      Lines 16 to 18 in 3886b61

      a {
      @apply underline;
      }
    • a {
      color: inherit;
      text-decoration: underline;
      }
    • ui/src/normalize.css

      Lines 40 to 42 in 3886b61

      a {
      background-color: transparent;
      text-decoration: underline;
    • (Not to mention that we do have custom CSS in the implementation of each component, in the form of class names, and those custom CSS rules override the base)
  • The stylesheets also have some conflicting rules:
  • normalize.css is supposed to match the original https://necolas.github.io/normalize.css/3.0.3/normalize.css, but I found some discrepancies: POC: try restoring normalize.css to the original huyenltnguyen/freeCodeCamp-ui#1
  • Tailwind provides a preflight stylesheet out of the box, and the purpose of the stylesheet is similar to normalize.css. However, we turned this option off in favor of our custom stylesheets (global-element-styles.css and normalize.css)
  • From what I understand, we added global-element-styles.css and normalize.css in because we wanted to mimic the /learn environment in Storybook, in order to develop components for /learn
    • /* the styled-elements and normalized are included here to replicate the presets that exist in the learn app */
      import React from "react";
      import "../src/normalize.css";
      import "../src/global-element-styles.css";
      import "../src/base.css";
    • According to the import order, if there is a conflict between global-element-styles.css and normalize.css, global-element-styles.css will take precedence.
  • Only colors.css and base.css are bundled

What we want to achieve

For the component library itself, we want:

  • A simplified styling strategy

For the library consumers, we want:

  • The color variables
  • A stylesheet for resetting default browser styles. This should be the same stylesheet that the component library uses internally

Approaches

I think we should start developing the component library as a standalone package, rather than having /learn influence it.

So I'd propose:

  • Removing global-element-styles.css since this comes from Bootstrap, and includes a lot of CSS customization, not just reset
  • Using Tailwind preflight for browser styles reset (this means simply flipping the preflight flag to true)
    • Here is a comparison between normalize.css and Tailwind preflight stylesheets: huyenltnguyen/freeCodeCamp-ui@f81770d (#2)
    • The differences between them aren't significant. But my concern with normalize.css is the library is not actively maintained, while Tailwind is an active project and its preflight stylesheet is written upon modern-normalize, which is... more modern.
    • We are already using Tailwind, so I think snapping back to Tailwind preflight would prevent stylesheets conflicts, and allow us to remove an additional dependency
  • Removing normalize.css, if we choose to use Tailwind preflight

As for the styling strategy in the component library, I think:

  • Each component should be styled using Tailwind classes. This should be the first option when it comes to styling a component.
  • If we want to override Tailwind globally, the rules should be added to base.css. As the file name suggests, the file should house very basic CSS styles, and we want to be mindful when adding changes as they will require overrides on the component level, which would bring inconsistencies.

Implications for the Bootstrap removal in /learn

Given that we tried replacing the Bootstrap stylesheet with normalize.css and the result was positive (ref), I don't think the Tailwind preflight would cause a catastrophe.

/learn has a huge global.css file that has all sort of CSS rules to override Bootstrap. I think those rules would help keep the UI intact (or mostly intact) when we swap the stylesheets. (The global.css file also needs a round of review and cleanup as part of the Bootstrap removal, but that's a separate topic.)

@huyenltnguyen huyenltnguyen self-assigned this Apr 10, 2024
@huyenltnguyen huyenltnguyen added the status: discussing Under discussion threads. Closed as stale after 60 days of inactivity. label Apr 18, 2024
@huyenltnguyen
Copy link
Member Author

@ahmaxed Not sure if it's your birthday, but this one is a surprise for you 😉

I'm tagging you for a review and inputs, but I can handle the implementation. I know it's a big wall of text, so please take your time, I'm not blocked by this issue.

@ahmaxed
Copy link
Member

ahmaxed commented Apr 22, 2024

It does not have to be my birthday. I always celebrate when I see well-thought out issues like this.
A few thoughts:

  1. At the time, I came to a conclusion that normalize is the industry standard comparing to preflight and it would make removing bootstrap easier since bootstrap was using it. If any of these assumptions are incorrect, we should move forward with preflight.

  2. There should be one set of presets, for the component library regardless of what is being overwritten in learn, etc.

  3. I think the main reason we added normalize and global element styles is that when the elements were imported to learn they would look different from Storybook. Might need to remove them, and see how they effect storybook and learn.

Finally, this is a great blueprint for the stylesheet consolidation. At the same time, it might be helpful to evaluate how it would impact the migration. If we decide to do this before or after the migration, I am on board either way. It is a task that we need to take care of at some point.

@huyenltnguyen
Copy link
Member Author

Thank you for going through my wall of text 😄


At the time, I came to a conclusion that normalize is the industry standard comparing to preflight and it would make removing bootstrap easier since bootstrap was using it.

I had the same impression until I had to dig deeper and compare normalize with Tailwind preflight.

From what I gathered:

  • Tailwind preflight uses modern-normalize and adds a couple more rules
  • modern-normalize is built on top of normalize, but with some improvements
  • The latest version of normalize is 8, and it's been 6 years since the last update

There should be one set of presets, for the component library regardless of what is being overwritten in learn, etc.

Just to clarify, by "presets", do you mean custom CSS rules and the rules would override the base Tailwind styles?

I won't object that, if that's what you mean 🙂 I think there are a couple of rules that we need to set to the component library, for branding and accessibility. Off the top of my head:

  • The focus outline style - I believe we have been manually adding this to each interactive component (button, input, link, etc.), but I think this rule should be global
  • Link underline - this is a custom rule and not from the original normalize stylesheet
    • ui/src/normalize.css

      Lines 43 to 44 in 379560e

      /* This is required in order to improve text readability in Arabic */
      text-underline-position: under;
  • Font family - we do have Lato set in the library, but not Hack-ZeroSlash

Anyway, we can discuss what global styles the library should have separately. For now, I only need to confirm if I understand the idea correctly.


So I'll go ahead and experiment the proposed approach.

The steps would roughly be:

  • @freecodecamp/ui
    • Try enabling Tailwind preflight
    • Remove global-element-styles.css and normalize.css, and probably cherry-pick some custom CSS from those files to base.css if the components look weird on Storybook
    • Bundle and release the new base.css (I actually don't need the new changes to be released in order to test, I just need the file content so that I can add to /learn locally)
  • /learn
    • Replace the Bootstrap stylesheet with the new base.css
    • Check and fix UI regression (we should pair this work with the CSS selectors/overrides cleanup in global.css, so that we don't have to manually testing things twice)

@ahmaxed
Copy link
Member

ahmaxed commented Apr 24, 2024

I meant normalizers by presets, and look forward to hear about your progress with the experimentation.

@huyenltnguyen
Copy link
Member Author

(Please ignore. I'm using this comment as my notepad.)

Rules to be removed from base.css

Rules to be added to base.css

Other notes

@huyenltnguyen huyenltnguyen added status: PR in works Work in Progress (WIP) Issues. and removed status: discussing Under discussion threads. Closed as stale after 60 days of inactivity. labels May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: PR in works Work in Progress (WIP) Issues.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants