Reputation: 19024
Suppose I have a container:
<div id="container"> This is a red apple </div>
How to color a word "red" with red color? Something like (pseudocode)
#container:[word="red"]{
color:red;
}
Is it possible to do this in pure CSS without introducing JavaScript or modifying the existing HTML?
Upvotes: 28
Views: 55240
Reputation: 209
So I have the same task, and the solution is pretty simple, but tricky You need to add :after pseudo-element and then:
#container:after {
content: "";
position: absolute;
width: 200px;
height: 50px;
background-color: red;
top: 10px;
left: 100px;
z-index: -1;
}
Adjust top, left, height, width for your case.
Upvotes: -1
Reputation: 1
I was dealing with this same issue. I had my base content wrapped in a
tag and all I did was surround each word I wanted highlighted in a tag and used CSS to change the colour of tags to red. Easy and simple.
e.g
<p>Base text, and then I want <p1>THIS</p1> word highlighted
</p>
p1 {
color: red;
}
Worked so well and did not mess up formatting at all.
Upvotes: -2
Reputation: 17
I don't understand why people say it's impossible to do it without JavaScript. I remember doing that kind of stuff with <span>
like so:
<div id="container"> This is a <span style="color:red">red</span> apple </div>
Upvotes: -2
Reputation: 3662
It can be easily Done with Jquery with a single line statements
Highlighting and remove highlight on button click
var text = $('div').text().replace(/Ipsum/g,"<span class='red'>Ipsum</span>");
$('div').html(text);
EDIT:
$('#id1').click(
function(){
var text = $('div').text().replace(/Ipsum/g,"<span class='red'>Ipsum</span>");
$('div').html(text);
}
);
$('#id2').click(
function(){
$( "span.red" ).each(function() {
$( this ).contents().unwrap();
});
}
);
.red {
color: red;
}
<div>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</div>
EDIT:
<input type="button" value="Click to highlight" id="id1" />
<input type="button" value="Click to remove highlight" id="id2" />
Upvotes: -1
Reputation: 11231
Use pseudo elements to add the coloured word and some careful positioning to cover the initial black instance. It's dirty, but it works.
#container
{
position: relative;
font-family: monospace;
margin: 0;
padding: 0;
font-size: 15px;
}
#container:after
{
content: "red";
color: red;
position: absolute;
left: 90px
}
EDIT: Also, a variation that works with proportional fonts (but doesn't render quite so cleanly, at least for me, in Chrome):
#container
{
position: relative;
margin: 0;
padding: 0;
}
#container:before
{
content: "This is a ";
position: absolute;
z-index: 2
}
#container:after
{
content: "This is a red";
color: red;
position: absolute;
left: 0;
top: 0;
z-index: 1
}
Upvotes: 0
Reputation: 4330
If you don't want to add html/javascript the simpel answer is NO you can't
Take a look at the following specification http://www.w3.org/TR/css3-selectors/#selectors
That are all available selectors for CSS3 and therefor it's simply impossible, and that's your answer.
You have 2 options left without changing the content one is all ready described here:
Upvotes: 1
Reputation: 2176
Simple but anyway RIGHT answer: NO.
Please, don't be rude with others in your comments, they took time to read your question, think about how they would solve such a problem, write an answer (or a comment) and... help YOU... they don't deserve be treated in a rude way.
Best regards and good look.
Miguel.
BTW: check Wrap certain word with <span> using jquery and http://forum.jquery.com/topic/wrapping-specific-words-inside-span-elements
Upvotes: 3
Reputation: 584
Here's some code that uses jQuery to wrap a class around the word red
, which can be colored.
<div id="container">This is a red apple</div>
$("#container:contains('red')").each(function(){
$(this).html($(this).html().replace("red", "<span class='red'>red</span>"));
});
Upvotes: -3
Reputation: 4592
Now if you allow me to use just a bit of javascript, and perhaps the caveat that I have no idea how well this will scale, might break a lot of CSS, and the implementation is a bit shoddy. That said, I think we can simply give css a bit of a hand by rewriting the HTML.
As you know we can add spans around the words and we can select that. But instead of just selecting the chosen one and attaching the style information, we span all the words. And attach the word as an value to the attribute "word". With the help of a way to get all the textNodes
, it might look something like
//adapted from https://stackoverflow.com/a/10730777/1480215
function makeHighlightable(){
var n, a=[], walk=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT,null,false);
while(n=walk.nextNode()) a.push(n);
for(var i=0;i<a.length;i++){
var newSpan=document.createElement("span")
var words=a[i].nodeValue.replace(/[\r\n]/g,"").split(' ');
for(var j=0;j<words.length;j++){
var escapedWord=words[j].replace(/[^a-zA-Z0-9-']/g,'').toLowerCase()
words[j]='<span word="'+escapedWord+'">'+words[j]+'</span>'
}
words=words.join(" ")
newSpan.innerHTML=words
a[i].parentNode.replaceChild(newSpan,a[i])
}
}
makeHighlightable()
With that in place, you can now do
#container [word=red]{ /* space instead of : */
color:#F00;
}
and it might possibly work.
Upvotes: 4
Reputation: 15089
This is a Vanilla JavaScript solution because it ain't possible with CSS. Not joking, read the specification. You can match on an element, the name of an attribute in the element, and the value of a named attribute in an element. I don't see anything for matching content within an element though.
Here's my shot at it. I am sure there is a sleeker way, but this is the gist of how it would start off as. Also, since there are a finite number of colors that you will want to colorify, it's nice to use a bunch of if
statements like I have.
A better technique of course would be to do it more programmatically by building a color dictionary and hence make the code organized. But this works, and it's Vanilla JS. Apparently, I didn't have expertise in Regex, so I am sure a few lines are unnecessary.
var text = document.getElementById("content");
var str = text.innerHTML,
reg = /red|blue|green|orange/ig; //g is to replace all occurances
//fixing a bit
var toStr = String(reg);
var color = (toStr.replace('\/g', '|')).substring(1);
//split it baby
var colors = color.split("|");
if (colors.indexOf("red") > -1) {
str = str.replace(/red/g, '<span style="color:red;">red</span>');
}
if (colors.indexOf("blue") > -1) {
str = str.replace(/blue/g, '<span style="color:blue;">blue</span>');
}
if (colors.indexOf("green") > -1) {
str = str.replace(/green/g, '<span style="color:green;">green</span>');
}
if (colors.indexOf("orange") > -1) {
str = str.replace(/orange/g, '<span style="color:orange;">orange</span>');
}
document.getElementById("updated").innerHTML = str;
Upvotes: 29
Reputation: 3852
Not to prove a point, but to answer your question - this is possible in CSS without JS: Example
In short: we set a black background color for text color and a red background image for the specific red string. We remove the original text fill using -webkit-text-fill-color
. The background is clipped to the text outline using -webkit-background-clip: text;
and the red image is sized and positioned over whatever text string we want to color.
Please note: I would never recommend using this for any live website. This works in webkit only as it's based on non-standard wekbit-specific CSS rules. And the color is not really bound to the colored text string - it's completely static.
Edit: Here's the CSS:
#container {
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
background-size: 1.5em 1em;
background-repeat: no-repeat;
background-position: 3.4em 0;
background-color: #000;
background-image: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5rooor8DP9oD/2Q==);
}
Upvotes: 18
Reputation: 490
Sadly CSS does not have any selector right now to achieve what you need. You have to use JavaScript or Server Side Scripting to achieve what you want.
Upvotes: 6
Reputation: 1697
Use <span>
for this.
<div id="container"> This is a <span class="red">red</span> apple </div>
CSS:
.red {
color: red;
}
Edit
It isn't possible without any additional Javascript or HTML. According to the CSS3 specification there is no such selector (There were thoughts about a :contains()
selector for CSS3). Also see this and this Question.
Upvotes: 1
Reputation: 651
You should use the span tag to surround the word "red"
<div id="container"> This is a <span>red</span> apple </div>
Then select this span using
#container span {
color: red;
}
Upvotes: -4