How do CSS ignore if the attribute is capitalized or lowercase?

Asked

Viewed 319 times

16

Imagine I have a situation where I need to style multiple links from my page, but only the links that end in .html, but I noticed that when trying to get the attribute href, I can only catch the ones that end exactly with .html, if it’s .HTML or .Html for example the link does not take the style. I would not like this to happen, I want to take the independent link whether it is capitalized or not.

Is there any way to fix this? Make CSS ignore if the attribute is capitalized or lowercase?

Follow an example of the problem:

a {
  display: block;
  padding: 10px;
  transition: all ease-out .2s;
  font-size: 1.5rem;
}

a:hover {
  transform: scale(1.2);
}

[href*="html"] {
  color: green;
}
<a href="pagina.HTML">link terminando em .HTML</a>
<a href="pagina.html">link terminando em .html</a>
<a href="pagina.Html">link terminando em .Html</a>

  • 1

    Once again an excellent question and once again learned something new researching about. :)

2 answers

19


The attribute CSS selector follows the pattern:

[atributo operador valor i]

Where:

  1. atributo: is the HTML attribute of the element
  2. operador: is the operator used to compare valor and the content of the attribute in the element. Operators can be:

    • =: when valor is exactly the same the content of the attribute;

      a[href="#"]{}
      /* Casa com todos os links que `href` sejam exatemente "#" */
      
    • ~=: when the content of the attribute is a separated by whitespace list and valor is a element of this list;

      button[class~="is-small"]{}
      /* Casa com:
          <button class="button is-small is-primary"></button>
          <button class="button is-active is-small"></button>
          <button class="is-small button"></button>
          <button class="is-small"></button>
      
         NÃO casa com:
          <button class="is-small-extra"></button>
          <button class="really-is-small"></button>
      */
      
    • |=: when the content of the attribute is exactly the same at the valor or begins with valor followed by a hyphen;

      html[lang|="en"]{}
      /* Casa com:
           <html lang="en"></html>
           <html lang="en-US"></html>
           <html lang="en-GB"></html>
      */
      
    • ^=: when the content of the attribute begins with valor;

      a[href^="#"]{}
      /* Casa com:
           <a href="#">
           <a href="#top">
           <a href="#modal">
      */
      
    • $=: when the content of the attribute ends with valor;

      a[href$=".html"]{}
      /* Casa com:
           <a href="/index.html">
           <a href="/header.html">
      */
      
    • *=: when the content of the attribute contains valor as substring;

      a[href*=".htm"]{}
      /* Casa com:
           <a href="/index.html">
           <a href="/page.htm">
           <a href="/abc.htmdef/index.cgi">
      */
      
  1. valor: is a string that will be compared to the contents of the attribute

  2. i: is a flag optional that indicates whether the comparison will be ascii case insensitive (only characters between a and z unstressed will be case insensitive).

So to marry any link whose href end with .html you would do:

a[href$=".html"]

But it won’t work with .Html, .HTML, .HtMl, etc... For this just add the flag i:

a[href$=".html" i]

The above example will match correctly with the possible variations of high cash.

Vale remembers that the rule:

a[href$=".abc" i]

Will marry .ABC, .AbC, but won’t work with .Ábc, or .äBc for being ascii case insensitive.

[EDIT] The flag s is also part of the spec and, unlike i, force the comparison to be ascii case sensitive.


Specs

After a good search for several versions and Drafts I ended up discovering that the flag i in the attribute selector is part of the draft of the selector module, that being a work in progress, its support is not yet complete.

However, with the exception of Internet Explorer, Microsoft Edge and Opera Mini, modern browsers already support this Feature, as shown in Can I Use.

Seeing the version 3 of the CSS selectors we have:

Attribute values must be CSS Identifiers or strings. The case-sensitivity of attribute Names and values in selectors depends on the Document language.

Which in free translation means:

Attribute values must be CSS identifiers or strings. O case-sensitivity of attribute names and values in selectors depend on the document language.

As our document is HTML, in the Case-Sensitivity and Comparison of Strings version 5.2 we have:

Except Where otherwise stated, string comparisons must be performed in a case-sensitive Manner.

In free translation:

Unless otherwise specified, string comparisons must be done case-sensitive.

And since there is no specification in the current spec, that would explain why case-sensitive by default in browsers.


Code

a {
  display: block;
  padding: 10px;
  transition: all ease-out .2s;
  font-size: 1.5rem;
}

a:hover {
  transform: scale(1.2);
}

[href*="html" i] {
  color: green;
}
<a href="pagina.HTML">link terminando em .HTML</a>
<a href="pagina.html">link terminando em .html</a>
<a href="pagina.Html">link terminando em .Html</a>

  • Show, did not know this. I will leave my answer only as an alternative for future research. + 1

  • Very good young man that’s right! Thank you for the reply!

  • 1

    Would you know if this is predicted by W3C/WHATWG? The only place I could find was this documentation on MDN that also quoted. With that in mind, do you know if it works on all browsers the same way? Also, the MDN documentation mentions that the i works only for ASCII characters, which would be interesting to add in the answer, since fóo would be different from foo even with the a flag.

  • @Andersoncarloswoss thanks for the suggestion. I edited the reply. Any recommendation just warn. Thanks.

  • Any specific reason for -1? If you could inform me to improve the answer it would be helpful...

0

Only with CSS I don’t know if it’s possible to do it, but I created a solution using jquery. I don’t know if it’s what you’re looking for, it’s just an idea of how it could be done.

I left the code all commented, in case you have any questions, ask.

$('a').each(function(){ //para cada link
   var attr = $(this).attr('href'); //pega o atributo
   var lower = attr.toLowerCase(); // transforma todos em minusculo 
   var html = lower.indexOf('.html'); //pega todos link que contem .html
   
   if(html != -1) { // aplica a todos links que tiverem .html
      $(this).css('color', 'green')
   }   
});
a {
  display: block;
  padding: 10px;
  transition: all ease-out .2s;
  font-size: 1.5rem;
}

a:hover {
  transform: scale(1.2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="pagina.HTML">link terminando em .HTML</a>
<a href="pagina.html">link terminando em .html</a>
<a href="pagina.Html">link terminando em .Html</a>
<a href="pagina.Htmlx">link terminando em .Htmlx</a>
<a href="pagina.xml">link terminando em .xml</a>

  • 1

    Thanks young, but with CSS I solved this time

  • 1

    Yes... I will leave the answer only as a second option for future queries.

  • 1

    You can do this only with Javascript vanilla, without jQuery, very simply: http://jsfiddle.net/acwoss/7nL4qcko/3/

Browser other questions tagged

You are not signed in. Login or sign up in order to post.