react-static-tweets icon indicating copy to clipboard operation
react-static-tweets copied to clipboard

CSS styles being overridden

Open raulfdm opened this issue 4 years ago • 4 comments

Hey there :wave:.

First, I'd say well done for this project. Really useful.

Just want to bring a point about styling. I currently try to use react-static-tweets in my blog and my global styles are gaining precedence over tweets style no matter where I add import 'react-static-tweets/styles.css'; (e.g. _app.tsx or component specifics).

That's probably because I'm using tailwind with typography plugin and the second one is being added way after react-static styles:

image

In a nutshell, all my global styles are impacting directly the tweets.

I was wondering the package could provide some sort of CSS scoping + reset (with whatever style it needs to be applied like no margins, no borders, etc).

Info

  • My blog PR: https://github.com/raulfdm/raulmelo-dev-web/pull/383
  • Live version: https://raulmelo-dev-git-replace-twitter-script-raulfdm.vercel.app/blog/cache-gatsby-github-actions

raulfdm avatar Mar 07 '21 12:03 raulfdm

Hey @raulfdm, thanks for the detailed bug report. Super helpful.

The style scoping can definitely be improved; not sure if it's possible to fully override / reset the styles unless we use a shadow DOM, but I'm sure that tailwind has some ability to add scoping at their level too.

Will follow up on this when I have time, but tbh I'm pretty swamped these days so it may be awhile.

cc @DaniGuardiola 😄

transitive-bullshit avatar Mar 07 '21 15:03 transitive-bullshit

Hey @transitive-bullshit , thanks for the answer.

I'm not 100% sure if I can do something related to tailwind/typography because the overall goal is exactly having global styles for any element inside prose class. Since the tweet will be part of a post (which has a prose scope, the style will be applied straight away. But anyways, I'll try to investigate that as soon I have some free time.

A strategy from library could be:

  • Scoping style using #id + .class strategy to have a high precedence score;
  • Using some pre-processor like SASS to split and compose a final css (also using tooling strategies to gain precedence)
  • Using some post-processo like PostCSS to do the same thing as mentioned to SASS
  • Using emotion/styled component to do the previous strategy but using CSS-in-JS strategy (also generating css file)

Any option will have pros and cons.

If you're open, I can try to come up with some solution.

raulfdm avatar Mar 11 '21 07:03 raulfdm

I've worked with the typography plugin too. The issue is that the plugin doesn't just style direct descendants of .prose. For example, every p, no matter how nested, gets selected.

I'm sure that tailwind has some ability to add scoping at their level too.

Unfortunately, this is not the case for this plugin, and in fact, I'd argue it's a larger issue.

Normally, when styling the elements inside an article, you're gonna want to target nested ones so that, for instance, bulleted lists inside quotes are styled properly. This results in a situation where every li is "globally" styled, but only for descendants of your article element (with the tailwind plugin, this root element is the one with the .prose class).

What this boils down to is that those styles are going to affect any elements even if inside the tweets.

There is an issue in the Tailwind plugin repo that discusses this, with a few workarounds. There's also this Twitter thread by Adam Wathan (tailwind creator).

It's just a hard problem.


Here are a few solutions from this package's perspective:

As @transitive-bullshit pointed out, a clean way to prevent elements inside tweets from getting selected is to use shadow dom. This could be a very nice way to achieve this, as I'd argue:

  • Embedded tweets already have something similar, as they use iframes that prevent the leakage of CSS into them.
  • I don't think we want to support customizing inner tweet styles with custom CSS.

However, there is one big blocking issue with this approach: there is no SSR support for shadow DOM. There is a proposal for declarative shadow DOW that would allow it, but for now it's just not an option.

Another option (let's call it "option B") is to have resets for everything (as mentioned by @raulfdm). This option doesn't really work in my opinion, because:

  • You cannot predict every single property that needs to be reset.
  • You are adding a bunch of additional CSS that bloats the bundle.
  • It is very unpredictable and hard to maintain.

ℹ️ PD: before I finished writing this comment I realized that something like all: initial; can be used to reset everything. Nice!

Option C could be just using plain divs for everything (instead of semantic elements) as those often don't get styled in these situations (the typography plugin doesn't, for instance), and a few minor resets for basic props (like margin, padding, etc) are affordable.

Personally, I'd go for option B, and option A when SSR shadow DOM is a reality (very long term).


In conclusion, this is (unfortunately) not a unique problem with react-static-tweets. For example, every piece of JSX in an MDX document can potentially have this issue. We can help with the resets, and with shadow DOM encapsulation in the future, but the issue is fundamentally outside the scope of this package.

An issue I'm personally gonna have to deal with.

I'll work on this a bit soon.

DaniGuardiola avatar Mar 12 '21 09:03 DaniGuardiola

Working on this... https://github.com/transitive-bullshit/react-static-tweets/pull/18

DaniGuardiola avatar Mar 31 '21 09:03 DaniGuardiola