1

I've developed a JavaScript Bookmarklet that have appended div to the current page.

But problem is that, when div and its content loaded because of pages' original CSS codes (Bookmarklet has its own CSS as well), my div's appearance corrupts.

I mean, on every page, some of elements looks different (sometimes labels' heights, sometimes textarea's backgroundcolor, etc.)

Is there a way to correct this fault that you know? It can be a CSS or JavaScript solution.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Alper
  • 1,067
  • 2
  • 17
  • 35

3 Answers3

2

Is there any way to correct this fault that you know?

Yes, define every relevant property inside the DIV and !important:

<div style="width: 300px !important; line-height: 1em !important....">

there is no other perfectly fail-safe way. All external widgets I've seen do it this way.

Pekka
  • 418,526
  • 129
  • 929
  • 1,058
  • Thanks for so rapid answer :)I am using CSS file not inline css codes, should i add !important to all lines of CSS codes? – Alper Jan 30 '11 at 21:05
  • 1
    @Alper you will need to make it inline CSS codes to be safe. It sucks big time, but it is the only 100% safe way. Alternatively, if your CSS rules are all targeting an element with an `id` (e.g. `#mainwidget a li { ... }` this should be specific enough (and override other CSS) in most cases. The rules behind this are called CSS specificity, see e.g. [this question](http://stackoverflow.com/questions/2809024/points-in-css-specificity) for pointers. – Pekka Jan 30 '11 at 21:08
  • Wow, its very intresting point.. I did not know this :S I am using css file as described before but all elements that having a problem to corrupt has their own id's. So adding "!important" to all id styles will solve my problem isn' it? – Alper Jan 30 '11 at 21:19
  • @Alper adding important to all id styles will make fairly sure it will work; only inline CSS in combination with !important will make 100% sure. – Pekka Jan 30 '11 at 21:20
  • 1
    Just a quick note that with inline styles you don't need !important. Inline styles have the highest specificity possible, so nothing will be able to override them. – Ryan Doherty Feb 01 '11 at 18:24
  • 1
    @Ryan I used to think so too, but it is incorrect. http://blogs.sitepoint.com/2009/05/27/override-inline-css/ – Pekka Feb 01 '11 at 18:25
2

It sounds like what you're saying is the page's CSS overrides your default styling of the content you inject. This is probably due to one of two things: not specifying every style attribute (and using relative values) for your content or your specificity isn't high enough.

Specify every style attribute

Let's say your content looks like this:

<div id="#cool-bookmarklet">Here is some content</div>

And your CSS looks like this:

#cool-bookmarklet {
    color: #000000;
    font-size: 80%;
}

Two problems with the above. Only two style attributes are declared, therefore every other attribute will be inherited from other styles. What if the page had CSS like this?

div {
    width: 70%;
    background-color: #000000;
}

You'll have problems because that CSS applies to your content (the div). Your div 'cool-bookmarklet' will be 70% the width of its parent and have a black background color. Not good.

Also, the font-size is a relative value, meaning it will be 80% of whatever the inherited value is. So if the font-size specified by the page is 10px, your font will be 8px. Here it's probably best to use explicit sizing to avoid any issues of inherited styles.

This is how your CSS should look to avoid inherited styles:

#cool-bookmarklet {
    color: #000000;
    font-size: 12px;
    width: 400px;
    background-color: #ffffff;
    margin: 0;
    padding: 0;
    font-weight: normal;
    /* etc, etc */
}

Specificity

There's a part of CSS that many people don't learn (and took me a while to understand) and it's called specificity. Specificity is used by browsers to determine what CSS styles to apply to elements when two selectors conflict.

From the CSS spec:

A selector's specificity is calculated as follows (from the spec):

  • Count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
  • Count the number of ID attributes in the selector (= b)
  • Count the number of other attributes and pseudo-classes in the selector (= c)
  • Count the number of element names and pseudo-elements in the selector (= d)

Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.

So a = styles in a style attribute of a html element. b = id selectors, c = class names and attributes, d = tag names. The selector with the highest specificity 'wins' if two selectors target the same element.

It's a little confusing, but you get the hang of it after a few tries.

Let's say you have these two rules in your CSS:

#cool-bookmarklet { color: red; }
div { color: blue; }

And the content:

<div id="cool-bookmarklet">Here is some content</div>

The selector '#cool-bookmarklet' would have a specificity of 100 (a=0, b=1, c=0, d=0). The selector 'div' has a specificity of 1 (a=0, b=0, c=0, d=1). '#cool-bookmarklet' would win and the div will have red text.

This is relevant because if your bookmarklet injects a stylesheet to style your content, other CSS on the page could override it if the specificity is higher. It's often easiest to give your content an ID (which has a high specificity 'b'). This allows you to target your content and not worry about other styles overriding.

Hope that helps!

Ryan Doherty
  • 37,071
  • 3
  • 51
  • 62
0

I don't fully understand the question. Perhaps a little snippet would help?

If you are worried that existing styles might override the styles on the elements you are dynamically adding, you can add the !important tag. But if the styles are inline (which is invariably what happens with bookmarklets) there should be no need for that.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
SamGoody
  • 11,846
  • 8
  • 70
  • 84
  • Actually and surprisingly to myself as well, `!important` rules *can* override inline CSS if they are specific enough. One needs to use `!important` inside the inline CSS to be 100% sure. – Pekka Jan 30 '11 at 21:06
  • I'am injecting a javascript and css (not inline css styles) files and js file contains a div with its content. And i want to learn that, how can i enforce my css file to use? – Alper Jan 30 '11 at 21:09