jeff
jeff

Reputation: 3742

Dynamic CSS style class that has a space or comma

I am setting a style class dynamically based on the status value such as:

<h:outputText value="#{item.status}" styleClass="#{item.status}"/>

And a few rendered examples:

<span class="Incomplete">Incomplete</span>
<span class="Expired">Expired</span>
<span class="Expiring Soon">Expiring Soon</span>
<span class="Incomplete, Overdue">Incomplete, Overdue</span>

The value is in a database that I don't control. How do I do the CSS styles to target these? Even though the last two have a space and a comma, they are all really single classes.

This is what I have that works, but is it working by a fluke or is the right way?

For either Expired or Incomplete I want red:

.Expired, .Incomplete {
    color: white;
    background-color: red;
}

For an Expiring Soon I want yellow

.Expiring, .Soon {
    color: black;
    background-color: yellow;
}

An Incomplete, Overdue:

.Incomplete, .Overdue {
    color: white;
    background-color: red;
}

Upvotes: 3

Views: 513

Answers (3)

dognose
dognose

Reputation: 20899

For either Expired or Incomplete I want Red

.Expired, .Incomplete {
    color: white;
    background-color: red;
}

That's correct: OR

An Expiring Soon I want Yellow

.Expiring, .Soon {
   color: black;
   background-color: yellow; }

Here you should use AND, meaning no comma, no whitespace:

.Expiring.Soon {
   color: black;
   background-color: yellow;
}

(Else, every entry that is EITHER .Expiring OR .Soon will be yellow.)

The invalid comma in the HTML (CSS classes are separated with whitespaces) - I'm not sure about if it has an impact. It might depend on the browser, whether it parses this as two classes (Incomplete and Overdue) or even as two classes with one containing a comma: (Incomplete, and Overdue)


I did some quick tests about the Comma. It seems like the browser (Internet Explorer, Chrome, and Firefox) are ignoring classes that contain a , inside the HTML markup.

That means, your last example

<span class="Incomplete, Overdue">Incomplete, Overdue</span>

is just rendered as

<span class="Overdue">Incomplete, Overdue</span>

.test1 {
  background-color:red;
}

.test2 {
  border:2px solid blue;
}
<div class="test1, test2">
  with comma after test1
</div>

<div class="test1 test2,">
  with comma after test2
</div>

<div class="test1,test2">
  with comma no whitespace
</div>

<div class="test1 , test2">
  with comma double whitespace
</div>

Upvotes: 1

sol
sol

Reputation: 22949

If you can't change the HTML you could target like so...

.Expired,
.Incomplete {
  color: white;
  background-color: red;
}

.Expiring.Soon {
  color: black;
  background-color: yellow;
}

.Overdue {
  color: white;
  background-color: blue;
}
<span class="Incomplete">Incomplete</span>
<span class="Expired">Expired</span>
<span class="Expiring Soon">Expiring Soon</span>
<span class="Incomplete, Overdue">Incomplete, Overdue</span>

Upvotes: 0

Marvin
Marvin

Reputation: 10092

This is what I have that works but is it working by a fluke or is the right way?

Your examples only work because in these specific examples CSS handles your single class as two separate classes. Especially this one:

<span class="Incomplete, Overdue">Incomplete, Overdue</span>

.Incomplete, .Overdue {
    color: white;
    background-color: red;
}

only works because of the .Overdue. To use commas and spaces in class names you would have to do it like this:

[class="Incomplete, Overdue"] {
  color: white;
  background-color: red;
}
<span class="Incomplete Overdue">Incomplete Overdue</span>
<span class="Incomplete, Overdue">Incomplete, Overdue</span>

The above is called attribute selector.


It is also possible to escape some characters like the comma in CSS (.Incomplete\, { ... }). For the whitespace thing you could simple combine this with the concept of grouping CSS selectors. In fact there are two selectors in the HTML .Inclomplete, and .Overdue but with the following CSS we can say that only the combination of both (with a whitespace in between) should be selected (which then would behave like a single class):

.Incomplete\,.Overdue {
  color: white;
  background-color: red;
}
<span class="Incomplete Overdue">Incomplete Overdue</span>
<span class="Incomplete, Overdue">Incomplete, Overdue</span>
<span class="Overdue">Overdue</span>

Upvotes: 2

Related Questions