10

We are developing a bookmarklet, and when the bookmarklet loads on different websites, eg: cnn.com, bbc.co.uk, yahoo.com it displays in various styles and we have struggle to reset these styles.

The bookmarklet content is in the current page DOM and not in an iframe (because we need cookies and access to DOM).

We tried using CSS reset, but that resets only some basic stuff, like margins. And pages where for example there is a custom form, or rounded table rectangles it inherits and it should not.

Is there a way that we can completely isolate this DIV area in the current page to look only as we want?

Pentium10
  • 204,586
  • 122
  • 423
  • 502
  • 2
    why not give it a unique id and design it to your liking? – Tomer Jul 23 '12 at 09:07
  • We tried that so, but the problem is that we NEED to define values EVERY css property. And I think that is overkilling. – Pentium10 Jul 23 '12 at 09:17
  • 2
    You don't really have a choice, if you embed your div in an existing page with an existing style sheet, there is no way to override those styling but writing your own. – Tomer Jul 23 '12 at 09:20

4 Answers4

1

How about trying to replace your div with some obscure element that is unlikely to be on their pages.

eg. b or em or i or maybe even one of the newer html5 elements if you're not fussed about browser support.

And styling them to display: block to function like a div which is a block element.

Your resultant HTML is not going to be valid or pretty, but it's a bookmark so, meh.

Short of that, a really good reset is what you'll need.

Or you'll just have to live with slight differences in your styling.

Moin Zaman
  • 25,281
  • 6
  • 70
  • 74
  • This is genial but INPUT and other stuff can't be replaced. – Pentium10 Jul 23 '12 at 09:43
  • 2
    See a more advanced version of my answer here: http://stackoverflow.com/questions/3019277/how-can-i-reset-styles-for-a-given-html-element – Moin Zaman Jul 23 '12 at 09:46
  • Also, people might just use `*{font-family: 'Comic Sans MS' !important;}` so using obscure elements won't help here as well. – m90 Jun 20 '14 at 18:56
1

We end up using https://github.com/premasagar/cleanslate

CleanSlate is an extreme CSS reset stylesheet. It is used to reset the styling of an HTML element and all its children, back to default CSS values. It is composed exclusively of !important rules, which override all other types of rules.

Pentium10
  • 204,586
  • 122
  • 423
  • 502
0

Well, you can use either the unique id and adding !important to each property afterwards - for resetting the generated element in the DOM - or you could use the new scoped attribute in "HTML5".

But that may result in problems with all explicit "inherit" valued styles on that element or the parents. For example, relative font sizes will result in problems, too.

Therefore is the experimental scoped attribute on the style section, but last time I tried it only Chrome/Chromium supported it, Firefox may have landed support for it recently, too - because there was a huge discussion on the mailing list.

http://updates.html5rocks.com/2012/03/A-New-Experimental-Feature-style-scoped

Edit:

Another solution could be to use a custom element that is not in the DOM by default. Something like document.createElement("thisisfrommyapp"); You can style them like other elements, but have to apply display:block or whatever behaviour want for them.

Also, IE allows using them, but you actually need to insert them into Tridents' parser before. If you want to use them in HTML, you have to do the createElement() before the DOM is parsed (so it's most likely inside the head of your document).

<html>
<head><script>document.createElement('customelement');</script></head>
<body><customelement>is stylable in IE8, too</customelement></body>
</html>

You have to do the createElement stuff for Trident only, because otherwise you will result in weird parsing behaviours due to their display:inline-block defaulted model :)

If you are using XHTML on the website for whatever stupid reasons (there are no valid reasons to use XHTML over HTML, due to parsers stripping out XML tags anyways), you should use a custom namespace for it.

~Cheers

Christoph Martens
  • 277
  • 1
  • 2
  • 10
  • The experimental scope attribute indeed could work, but it is a far future wish. Maybe all major browser will adopt in the next 10 years. – Pentium10 Jul 23 '12 at 09:34
  • I read the linked article, but still the biggest issue is the INPUT tags. How would you replace them? – Pentium10 Jul 23 '12 at 12:05
0

Follow this 2 steps to sandbox a container.

<div class="namespace-box">
    <h1 class="namespace-title">Title</h1>
    <p class="namespace-text">Text</p>
</div>
  1. Unset all properties of the container's namespace, all: unset; is just a placeholder:
[class*="namespace-"],
[class*="namespace-"]:after,
[class*="namespace-"]:before,
[class*="namespace-"]:hover:after,
[class*="namespace-"]:hover:before {
    all: unset;
    // properties to be unset
}
  1. Use a Grunt or Gulp task to add the attribute selector to your original CSS. This increases the cascade and prevents overrides by the unset hack:
[class*="namespace-"].namespace-box,
[class*="namespace-"].namespace-title,
[class*="namespace-"].namespace-text {
    // original properties
}

You can automate the specification with the postcss-increase-specificity task.

Enjoy your bulletproofed container.

Henry Ruhs
  • 1,533
  • 1
  • 20
  • 32