CSS3 problem

Posted on 2014-01-14
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.

Question by:elepil
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
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.

Author Comment

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.
LVL 30

Accepted Solution

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:

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

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

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.


Author Closing Comment

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. :)

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Find out what you should include to make the best professional email signature for your organization.
Today, the web development industry is booming, and many people consider it to be their vocation. The question you may be asking yourself is – how do I become a web developer?
In this tutorial viewers will learn how to embed custom externally-hosted Google Fonts using the Google Font API in CSS Go to the Google Fonts website at Browse or search based on font properties or name to find a suitable font for…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

705 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