59

At W3Schools they declare both | and ^ to mean: Select an element with an attribute starting with a specified value.

So what's the difference?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
alex
  • 7,551
  • 13
  • 48
  • 80
  • 13
    As an add on to my answer, please don't mistake W3Schools for W3C. They are not the same nor is W3Schools related to W3C. Not all information provided by W3Schools is spot on. Have a look at http://www.w3fools.com/ when you get time. – Harry Dec 30 '15 at 14:12
  • @Harry, I got my start in web development about 7 years ago on W3schools. I soon realized the many deficiencies on that site. To be fair, however, they've improved a lot in recent years. They're obviously no match for the W3C, but for beginners and intermediate study, they're not so bad. – Michael Benjamin Dec 30 '15 at 15:57
  • 3
    @Michael_B: Trust me, I've used W3Schools a lot too and which is why I only said "Not *all* information provided by them is spot on" :) I wouldn't say never use W3Schools but just that always cross-verify with the official specs when in doubt. – Harry Dec 30 '15 at 15:59
  • Said more frankly: do not rely on w³schools. w³schools is to information what UB is to an algorithm. – Déjà vu Jan 16 '16 at 05:22

4 Answers4

49

Caret (^): selects an element (<h1>) where the value of the specified attribute (rel) starts with a certain value (val):

h1[rel^="val"] { /** formatting */ }

h1[rel^="friend"] { color: blue; }
<h1 rel="friend-external-sandwich">I'm Blue.</h1>
<h1 rel="friend2-external-sandwich">I'm Blue.</h1>
<h1 rel="external-sandwich">I'm Black.</h1>

Pipe (|): selects an element (<h1>) where the value of the specified attribute (rel) is either exactly the value (val) or starts with the value immediately followed by - (val-):

h1[rel|="val"] { /**formatting */ }

h1[rel|="friend"] { color: red; }
<h1 rel="friend-external-sandwich">I'm Red.</h1>
<h1 rel="friend2-external-sandwich">I'm Black.</h1>

More information about this selectors you can find here: https://css-tricks.com/attribute-selectors/ or on the official CSS specification: https://www.w3.org/TR/css3-selectors/#attribute-selectors

Sebastian Brosch
  • 42,106
  • 15
  • 72
  • 87
41

As w3schools declare both | and ^ select attribute starting with a defined value

No, the | is not used to select elements whose attribute value start with a certain value.

Here is what the W3C Spec says about these selectors. (emphasis is mine)

[att|=val]

Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by "-" (U+002D).

[att^=val]

Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.

So, the | symbol in the attribute selector would select only elements whose attribute value is either exactly the given value or starts with the given value followed by a hyphen.

As you can see in the below snippet, the attribute selector which uses | ([data-test |= 'val']) doesn't select the element when the attribute value is like valid whereas the attribute selector with ^ ([data-test ^= 'val']) does.

div[data-test |= 'val'] {
  color: beige;
}
div[data-test ^= 'val'] {
  background: red;
}
<div data-test='val'>Hello</div>
<div data-test='val-id'>Hello</div>
<div data-test='valid'>Hello</div>

In a more real-world scenario, the attribute selector with pipe (|) can be used to select elements and apply specific styling depending on their language (which can be set using the lang attribute). As we can see in the snippet, |= 'en' selects all elements whose lang attribute is either en or en-GB or en-US (or any other en-* for that matter).

As the spec states, the primary intention of this selector was to allow language subcode matches but as BoltClock points out, this has by and large been superseded by the :lang pseudo-class selector.

div[lang |= 'en']{
  font-size: 16px;
  background: steelblue;
}

div[lang |= 'zh']{
  font-size: 14px;
  background: mediumslateblue;
}

div{padding: 4px;}
<div lang='en'>English: The grass is green in colour.</div>
<div lang='en-GB'>English (UK): The grass is green in colour.</div>
<div lang='en-US'>English (US): The grass is green in color.</div>
<hr>
<div lang='zh-CN'>Chinese (Simplified): 草是绿色的。</div>
<div lang='zh-TW'>Chinese (Traditional): 草是綠色的。</div>

(Translations were by Google. Any mistake was unintentional)

Additional Information: The attribute selector which uses pipe (|) was introduced in CSS2 and the attribute selector which uses the cap/caret (^) was introduced in CSS3.

Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
10

Simply put:

E[foo|="en"] matches...

an E element whose "foo" attribute has a hyphen-separated list of values beginning with "en"

E[foo^="bar"] matches...

an E element whose "foo" attribute value begins exactly with the string "bar"

Expanded Info:

[att|=val]

Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by "-". This is primarily intended to allow language subcode matches (e.g., the hreflang attribute on the a element in HTML).

[att^=val]

Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.

Source: http://www.w3.org/TR/css3-selectors/#selectors


Examples

HTML

<ul>
    <li title="test">testing attribute selectors</li>
    <li title="testing">testing attribute selectors</li>
    <li title="testing test">testing attribute selectors</li>
    <li title="testing-test">testing attribute selectors</li>
    <li title="test-testing">testing attribute selectors</li>
</ul>

Testing the pipe (|) selector.

li[title|="testing"] { background-color: aqua; }

enter image description here

Testing the caret (^) selector.

li[title^="testing"] { background-color: pink; }

enter image description here

#pipe > li[title|="testing"] {
  background-color: aqua;
}
#caret > li[title^="testing"] {
  background-color: pink;
}
<p>
  <code>Testing the pipe (|) selector.</code>
</p>
<ul id="pipe">
  <li title="test">testing attribute selectors</li>
  <li title="testing">testing attribute selectors</li>
  <li title="testing test">testing attribute selectors</li>
  <li title="testing-test">testing attribute selectors</li>
  <li title="test-testing">testing attribute selectors</li>
</ul>

<hr>

<p>
  <code>Testing the caret (^) selector.</code>
</p>
<ul id="caret">
  <li title="test">testing attribute selectors</li>
  <li title="testing">testing attribute selectors</li>
  <li title="testing test">testing attribute selectors</li>
  <li title="testing-test">testing attribute selectors</li>
  <li title="test-testing">testing attribute selectors</li>
</ul>

jsFiddle

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
3

Actually

[attr ^= value] is value*
Caret (^) means starting with "value" (and obviously exact value as well)

[attr |= value] is value OR value-* (i.e. [attr = value],[attr ^= value-])
Pipe (|) means either exact "value" or starting with "value-" (succeeded by dash (-))

Example:

<!DOCTYPE html>
<html>
    <head>
        <style>
            /* [lang=en],[lang^=en-]*/
            [lang|=en] {
                background: cyan;
            }

            [lang^=ar] {
                background: lime;
            }
        </style>
    </head>
    <body>
        <p lang="en">Hello!</p>
        <p lang="en-us">Hi!</p>
        <p lang="en-gb">Ello!</p>
        <p lang="ens">Not me!</p>

        <p lang="ar">سلام</p>
        <p lang="ar-sa">السلام علیکم</p>
        <p lang="ar-ae">السلام علیکم و رحمۃ اللہ</p>
        <p lang="ars">Me as well</p>
    </body>
</html>
TalESid
  • 2,304
  • 1
  • 20
  • 41