James Andrews
James Andrews

Reputation: 3304

How to insulate HTML widget from external CSS

I've developed an instant messaging component using AngularJS that adds instant messaging functionality to any web page. The component is fairly complex it's style sheet runs to about 800 lines.

I'm having a problem when the component is deployed to third party websites. Sometimes the CSS from the host website affects the styles of the chat widget.

Login and sign up buttons made upper case

The screenshot is used when the component is added to a fresh Wordpress install. You can see that the button text is overridden by the Wordpress style to be upper case.

The problem is this component will be deployed to tens of thousands of websites so it wouldn't be practical to solve each small issue on a case by case basis. It would also be impossible to know if these changes would have a knock on affect to another website.

The approach I'm currently considering is to create a very comprehensive reset stylesheet - I'd override all possible styles on all elements. That would give me a fresh canvas to start with.

This seems like a pretty onerous task so I was wondering if anyone had devised a better solution?

Note:

An iFrame isn't possible because the chat has to overlay the original web page

Upvotes: 4

Views: 1121

Answers (2)

Luca
Luca

Reputation: 9705

  • namespace your classes to avoid any possible clashes
  • reset all styles (super tedious I agree)

if you really want to go hardcore, I would not recommend any of the below but they are available options:

  • use !important
  • use inline styling with the above

Upvotes: 2

MiniRagnarok
MiniRagnarok

Reputation: 959

Like Luca suggested, using a namespace is the correct answer.

While you could use !important or an iframe I dislike both of those answers and here's why.

Why you shouldn't use !important

  1. Your goal is to create CSS that can't be overridden. Using !important doesn't actually solve that problem. I could still override your styling by using the same specificity that you have. It is however, a pain to do.
  2. Mozilla specifically recommends that you don't do it.
  3. As you've said yourself, this could be used on 100k+ websites. The likelihood that you're going to override someone else's styling is pretty high. Using !important is going to ruin their day. You've effectively taken the cascading out of CSS. As a rule, use the least amount of specificity that you can comfortably get away with. This makes everyone's life easier.

Why an iframe is not the answer

I'm not nearly as opposed to using an iframe as I am to using !important but there is some negatives that you need to be aware of.

  1. iframes give control to you (the plugin maker) at the cost of the user. e.g. The user has no choice in being able to match your iframe's responsiveness with their site. It's entirely likely that some user is going to have a specific breakpoint that isn't going to play nice with your plugin.
  2. Your styling is impossible to override. This point could be seen as a positive for you but I find that it's a negative to the user. Being able to style the colors of your plugin helps make the plugin a part of the site. It's a guarantee that your plugin's colors won't mesh well with some sites. Letting the user change the colors is a must for me.

Using Namespaces

The idea is pretty simple. Let's say that your app is called SuperIM2000. All you do is make sure that there's a container with the same class name and that you use it to target your styling. This has the added benefit of allowing you to use very simple class names e.g. button.

HTML

<div class="superIM2000">
    <input class="button" />
</div>

CSS

.superIM2000 .button{
    color:#000;
}

As you can see, the specificity is very low. However, the likelihood that you're going to override someone else's styling is extremely low. This has a benefit to the user as well. It's possible that the button class is already used in their site and it can take advantage of any inheritance that you haven't overridden.

Upvotes: 2

Related Questions