Solved

CSS3 problem

Posted on 2014-01-14
4
301 Views
Last Modified: 2014-01-15
In my HTML file, I am using CSS3's attribute selectors:

p[name^="my"] {
    font-size: 30px;
    color: aqua;
}

p[name$="my"] {
    font-size: 40px;
    color: brown;
}

p[name*="my"] {
    font-size: 50px;
    color: darkorange;
}

They are used in my HTML file as:

<p name="mytext">This should be 30px and color aqua</p>
<p name="textmy">This should be 40px and color brown</p>
<p name="textmytext">This should be 50px and color darkorange</p>

But when I render my HTML document, they all seem to be 50px and darkorange, as if the last attribute selector overrides everything prior.

Is this the expected behavior??? Because my book does not say so.

Thanks.
0
Comment
Question by:elepil
  • 2
  • 2
4 Comments
 
LVL 30

Expert Comment

by:Alexandre Simões
ID: 39781433
Yep, this is the expected behavior.
The last selector always match on top of the 2 before and as it comes after it just overrides it.

This is a common behavior in CSS (nothing CSS3 specific) and it applies to all selectors.
It is in fact the behavior that makes it possible, for instance, to override styles defined in a file with styles defined in another file.

So your solution here is to move the last selector before the other 2:
p[name*="my"] {
    font-size: 50px;
    color: darkorange;
}
p[name^="my"] {
    font-size: 30px;
    color: aqua;
}
p[name$="my"] {
    font-size: 40px;
    color: brown;
}

Open in new window


Like this the first selector will only be the final one if "my" is somewhere in the middle which I think it's your goal.
0
 

Author Comment

by:elepil
ID: 39783013
Alex, thank you for your response. Your recommended solution clearly works, but your explanation totally confuses me.

You said, "The last selector always match on top of the 2 before and as it comes after it just overrides it.", and that makes absolutely no sense to me. Can you please elaborate on this?

I'm making this post not only to obtain a solution from more experienced CSS users like you, but I would also like to understand the thinking behind so I don't commit the same error in the future, so please bear with me.
0
 
LVL 30

Accepted Solution

by:
Alexandre Simões earned 500 total points
ID: 39784630
No problem mate, sorry I wasn't clear enough.

First some CSS parsing base theory:
CSS files are read sequentially from top to bottom.
This mean that if you specify the same property multiple times for the same element, the last one wins.

Also (and it doesn't really apply in this case but is important for you to know), css files are read in the order they are declared in the page. This means that something on a second css might override something else declared on a previous file.


Let me break the attribute selectors down:

p[name^="my"]
This will math all the elements with a name attribute which value begins with "my".
An example can be: "myname"

p[name$="my"]
This will math all the elements with a name attribute which value ends with "my"
An example can be: "namemy"

p[name*="my"]
This will math all the elements with a name attribute which value contains "my" anywhere. This means that this selector will always match the same as the above plus the cases where "my" appears in the middle, like: "thisismyname".


So, knowing that CSS is parsed sequentially from the top to the bottom, respecting your initial order and assuming an element name "myElement" we have:
1. p[name^="my"]  Match! ("myElement" starts with "my")
2. p[name$="my"]  Doesn't Match!  ("myElement" doesn't end with "my")
3. p[name*="my"]  Match! ("myElement" contains "my" somewhere)

From this example you'll see that as we read the css from top to the bottom, anything declared on the (3) will override the ones declared on (1).

So now lets fix it:
1. p[name*="my"]  Match! ("myElement" contains "my" somewhere)
2. p[name^="my"]  Match! ("myElement" starts with "my")
3. p[name$="my"]  Doesn't Match!  ("myElement" doesn't end with "my")

Now we started with the more generic selector at the beginning and declared the more specific after.
The generic selector (1) will match but if any of the specifics also match then they will override its value.

Hope it's clear now.
Anyway tell me if you still have any doubts about it.

Cheers!
0
 

Author Closing Comment

by:elepil
ID: 39784669
Thanks, AlexCode, it is crystal clear to me now! After your second clearer explanation, even your first explanation now makes sense to me. :)
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

As a result of several questions about how to use Bootstrap I thought it would be a good idea to write down the development aspect of creating a Bootstrapped website in as little time as possible. Part 1 of this article will only concentrate on g…
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
In this tutorial viewers will learn how to style a decorative dropcap for the first letter in a paragraph using CSS. In CSS, create a new paragraph class by typing "p.fancy": Then, to style only the first letter of the first sentence, include the ps…
In this tutorial viewers will learn how to embed an audio file in a webpage using HTML5. Ensure your DOCTYPE declaration is set to HTML5: : The declaration should display (CODE) HTML5 is supported by the most recent versions of all major browsers…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now