0

I have a css class, which changed the font color. I don't find a solution via CSS, how this class could only change the font color of letters.

CSS

.blue{color:blue;}

HTML

<span class="blue">stackoverflow</span>

I need a better solution for the brackets ()

<span class="blue">stack</span>(<span class="blue">x</span>)<span class="blue">overflow</span>

This should also work for:

<span class="blue">stack(x)overflow</span>

The brackets should be still in black. If it is impossible only with CSS, how do to this with JavaScript or PHP?

Grischa
  • 70
  • 8
  • 26

4 Answers4

2

If javascript (and jQuery) is acceptable to you, then this will achieve what you want.

In short it retrieves the text, cuts it into alternating parts of "text content" / "other content", and strings it all together again with "blue" applied to the "text content" parts.

function GetParts(text) {
  var parts = [];
  var index = 0;
  parts[index] = '';
  var isText = true;
  for (var i = 0; i < text.length; i++) {
    var c = text.charAt(i);
    var isLetter = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
    if (isLetter) {
      if (isText) {
        parts[index] += c;
      } else {
        isText = true;
        index++;
        parts[index] = c;
      }
    } else {
      if (!isText) {
        parts[index] += c;
      } else {
        isText = false;
        index++;
        parts[index] = c;
      }
    }
    console.log('index = ' + index + ', parts[index] = ' + parts[index]);
  }
  return parts;
}

function ChangeText() {
  // Find and then process all elements with css class '.OnlyLettersBlue'
  $('.OnlyLettersBlue').each(function() {
    var elem = $(this);
    var text = elem.text();
    var parts = GetParts(text);
    var result = '';
    for (var i = 0; i < parts.length; i++) {
      if (i % 2 == 0)
        result += "<span class='blue'>" + parts[i] + "</span>";
      else
        result += parts[i];
    }
    elem.html(result);
  });
}
span {
  font-size: 20px;
}

.blue {
  color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Text 1: <span class="OnlyLettersBlue">stack(x)overflow</span><br />
Text 2: <span class="OnlyLettersBlue">Some[--{thing}--]else</span><br />
<button onclick="ChangeText()">Colorize text</button>
Peter B
  • 22,460
  • 5
  • 32
  • 69
  • Considering there's no way to do it using pure CSS, it's an adequate answer, but implementing it with regex would have made it more readable. – Haroldo_OK Jun 26 '17 at 11:30
  • That may be true for regex experts, but undoable for me. Feel free to show your skills :-) – Peter B Jun 26 '17 at 11:32
  • @PeterB Thank you for your answer. I don't understand exactly how to use it. I see 2 lines, in which the Result line is showing the desired output. Which `id` should I add to `stack(x)overflow` – Grischa Jun 26 '17 at 11:46
  • 1
    You don't need an id, it is just something I used for this example, and you can choose to do it with an id or without an id (but then you need some other means to find the source + target `span`s). The span with `id="source"` produces the initial text, and the span with `id="result"` receives what is generated in my javascript `result` variable. You can also use a *single* span for both source and target, but for the example it seemed more clear to keep them separate. – Peter B Jun 26 '17 at 13:45
  • I understand, but nevertheless I don't know, what do add to stack(x)overflow to have source and result in one span. I have included the script and jQuery. – Grischa Jun 27 '17 at 07:53
  • 1
    I changed the snippet to find and modify all elements with a certain class named OnlyLettersBlue. That class itself has no css effect, it is used so the JS code can find them and then replace the plain text inside each with the necessary span tags (which now happens after a button press). – Peter B Jun 27 '17 at 08:23
1

Here'a a regex-based variant:

$(function() {

  var regex = /([\w\s]+)/g;
  
  $('.blueLetters').each(function() {
    var elem = $(this);
    var text = elem.text();
 var result = text.replace(regex, '<span class="blue">$1</span>');
    elem.html(result);
  });
})
span {
  font-size: 20px;
}

.blue {
  color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<span>I'm not affected (really)</span><br>
<span class="blueLetters">stack(x)overflow</span><br>
<span class="blueLetters">Something (else)</span><br>
<span>Neither am I</span><br>

Basically, the regex expression above uses those features:

  • [abc] matches any of the characters between the brackets;
  • A+ means 'A' repeated one or more times;
  • \w matches any alphanumeric character;
  • \s matches any whitespace character, including tabs and line breaks;
  • (something) creates a group;
  • /something/g means the expression should be applied globally, instead of once only.

Recommended reading: https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions

Haroldo_OK
  • 6,612
  • 3
  • 43
  • 80
  • Thank you for your answer. I don't know, how to use it, if I want only the result. I will use the css class for strings with and without brackets. I have already read the answer to my question in the comments of the first JQUERY answer, but I didn't know, what to do. – Grischa Jun 26 '17 at 16:57
  • It works identically to @PeterB 's solution, it is just the implementation details that are different. – Haroldo_OK Jun 26 '17 at 18:31
  • I understand, but nevertheless I don't know, what do add to `stack(x)overflow` to have `source` and `result` in one span. I have included the script and jQuery. – Grischa Jun 26 '17 at 19:00
  • How is it possible to add UTF-8 characters like for example: ü ä ß è in the regex expression. This characters shouldn't also not change the color and should be blue. – Grischa Jul 06 '17 at 14:33
  • That depends on the criteria you intend to use; see [this post about Regex with diacritics](https://stackoverflow.com/questions/20690499/concrete-javascript-regex-for-accented-characters-diacritics) and its answers in order to have a better idea of the possibilities. – Haroldo_OK Jul 06 '17 at 15:34
0

I don't think you can do this with CSS alone.

You might want to look at Lettering.js

Also, while the hack below is NOT exactly an answer to your question, it does have some limited uses.

just for fun.

.blue {
  color: blue
}

span:nth-child(1)::after {
  content: "("
}

span:nth-child(3)::before {
  content: ")"
}

span:nth-child(1)::after,
span:nth-child(3)::before {
  color: black
}
<span class="blue">stack</span><span class="blue">x</span><span class="blue">overflow</span>
I haz kode
  • 1,587
  • 3
  • 19
  • 39
0

Apologies for the late response

https://jsfiddle.net/vsdLx0xv/

I just wrapped the ( in a tag. It's not reserved (AFAIK) and it's short to make quick changes.

Then styled accordingly

<span class="blue">stack<c>(</c>x<c>)</c>overflow</span>

.blue{color:blue;}
.blue c{color:black;}

Couldn't find a way without wrapping the brackets without js

Gezzasa
  • 1,443
  • 8
  • 17