-
-
Notifications
You must be signed in to change notification settings - Fork 28.2k
Description
The Problem
The current architecture of rendering the card follows a more traditional approach where we concatenate raw svg strings to build a valid SVG markup.
- Build svg template
- Manipulate string
- Interpolate dynamic props
- Render card
Problem 1
The problem with this approach is that it's not very scalable specially when we consider the fact we have to handle precise pixel values and by default SVGs don't support flexible layouts, text wrapping and other vital layout engine features which are needed to build a complex card layout.
This approach has implemented since the start of github-readme-stats which worked fine early on, but as the cards grow in complexity it's becoming more and more harder to manage the layouts. For example we had implement all sorts of hacky workarounds to use FlexBox, TextWrapper, MeasureText and other features which are already present in any modern layout engine.
Problem 2
Second point is that manipulating strings like we do now poses a huge burden for us to properly interpolate all the pixel values which are needed and it's a manual process. There is no %, rem, em, or flexible units to work with in SVGs. Every single element on the SVG has to be carefully crafted to maintain their size/width/height/position. It's not fun to build cards.
Solution
The solution which I'm proposing to implement is by taking advantage of foreignObject in SVG.
Advantages of foreginObject
- Easy to build cards, we have all the power of flexible layouts, CSS & browser's layout engine.
- Browser support is good
- Trivial to build templates for cards
Low hanging questions
There are few things which we have to check first, one of them is if foreignObject is supported in github mobile or not, That's an issue because we don't know what kind of engine the github mobile app using.
Other thing is checking various browsers for compatibility and consistency of the styling and layout. Even though browser support is good, we still need to do some testing to make sure it's consistent across browsers.
Implementation plan
Over the next few weeks I'll be start implementing this feature and deploy it in a vercel preview link to test things out.
Feedback
I'll be needing feedback from the community and the core members (@rickstaa) to implement this & the feasibility of this.
Let me know what you folks are thinking about this approach we can discuss more on the pros and cons.