How to style text by a specific index? - html

I need to be able to bold text in an element(it doesn't need to work with pre, but i'd prefer it would).
for example:
This is the string i wish to display.
is there an ability to do that purely in html and css with indexes if yes then how can i do that? or should i use something else?
Edit: The text is dynamic. where to bold will be specified with *

Long story short, from what I know there is no way with CSS only to select text by text. So you will need to use javascript to achieve what you are after.
You can use replace()
// check all elments with given class
[...document.querySelectorAll('.check-those-p-tags')].forEach(function(element){
// iterate over all elements
var resultString = element.innerHTML.replace(
/the/g, // search for all (g = global) "the" in the innerHTML
'<span class="alert">$&</span>' // replace/wrap the "the" with some tags and class
// "$&" means => Inserts the matched substring.
);
element.innerHTML = resultString; // overwrite the innerHTML with the new string
});
.alert { color: red; font-weight: bold; }
<p class="check-those-p-tags">This is the string i wish to display.</p>
You can also write it almost in one line
[...document.querySelectorAll('.check-those-p-tags')].forEach(function(element){
element.innerHTML = element.innerHTML.replace(/the/g, '<span class="alert">$&</span>');
});
.alert { color: red; font-weight: bold; }
<p class="check-those-p-tags">This is the string i wish to display.</p>

Related

How do I change the size of text between capital and lowercase letters?

Is it possible to change the size of text based on whether it is a capital letter or if it is a lowercase letter within HTML/CSS? I am working with a font called Staatliches that only has uppercase letters, but I would like for the lowercase letters to be slightly smaller than the capital letters within the styling of the text. Is it possible to make this change within the CSS? Thank you!
There's not a wealth of character specific css selectors (like p::first-letter), so I think you're best bet would be to use JavaScript to execute some regex matching similar to ncubica's solution here and wrap the capital letters in a their own span.
Working Example Below:
function wrapCapsWithSpan (className) {
var regex = new RegExp(/[A-Z]+/g); //matches on groups of capital letters, remove the '+' to wrap individually
let largeCaps = document.querySelectorAll('.staatliches')
return [...largeCaps].map((p) => {
p.innerHTML = p.innerHTML.replace(regex, function(matched) {return "<span class=\"" + className + "\">" + matched + "</span>";});
});
};
window.onload = wrapCapsWithSpan("biggest-caps");
.staatliches {
text-transform: uppercase; // simulating Staatliches font
font-size: 10px;
}
.biggest-caps {
font-size: 40px;
}
<p class="staatliches">Large CAPITALS BIGgER</p>
<p class="staatliches">Second Paragraph!</p>

CSS to bold a varying length section of a paragraph up to a delimiter like a colon or hyphen

Is there a way to apply a bold style to the beginning of a paragraph up to a delimiter character--like a colon or hyphen? The value before the delimiter can be any length.
So a string like this:
Definition item: description or definition of the item....
would look like:
Definition item: description or definition of the item....
I get this result in javascript but its impossible to make in css :
( updated and added while loop )
function myFunction(str) {
var res = str.split(":");
var mynewres = "<b>" + res[0] + ": " + "</b>" + res[1];
var i = 2;
var newres = mynewres;
while (typeof res[i] !== 'undefined') {
newres = newres + ":" + res[i];
i++;
}
return newres;
}
var newtxt = myFunction("Note: This Function Don't Work Correctly If No Colones Are Used! That Means : You Must Use One Colone At Least!");
document.getElementById("LookHere").innerHTML = newtxt;
#LookHere {
font-size: 30px;
}
<span id="LookHere">
to add to my earlier comment :
CSS only offers the pseudo class :first-letter and :first-line to style text partially. To bold a text to emphase it, you can use the <em> or <strong> tag. <b> is also avalaible but that is HTML to structure your text.
For what it seems, there is an HTML structure to use that will describe itself these text content: the definition list(W3C) <dl><dt><dd>
The <dl> element represents a description list.
dt {font-weight:bold;}
<dl>
<dt>Definition item:</dt>
<dd>description or definition of the item....</dd>
</dl>
add some styles to set it on a line
dt {
font-weight: bold;
}
dt,
dd {
margin: 0;
display: inline;
}
<dl>
<dt>Definition item:</dt>
<dd>description or definition of the item....</dd>
</dl>
Wrap your title with <b></b>
<span><b>Definition item:</b> description or definition of the item....<span>
Also, you can use JS to handle this. (not recommended)
Just because this can be done does not mean that you should do this.
Manipulating the DOM just to change display is very bad practice.
Concern should be given to how the info is being generated in the first place.
That said here is a solution using jquery
$('p').each(function(e){
var title = this.innerText.substring(0, this.innerText.indexOf(':'))
var definition = this.innerText.substring(this.innerText.indexOf(':')).replace(":","").trim()
console.log("title:"+title);
console.log("definition:"+definition);
$(this).html("<strong>"+title+":</strong> "+definition)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Definition item: description or definition of the item....</p>
<p>another item: description or definition of the item....</p>
<p>new item: description or definition of the item....</p>
Allthough you should just edit it directly in the html. Here a jQuery free and flexible javascript solution:
var definitions = document.querySelectorAll('.definition');
for (var i = 0; i < definitions.length; i++) {
definitions[i].innerHTML = definitions[i].innerText.replace(/^[^:]+:/, '<b>$&</b>');
}
<p class=definition>Definition: This is something.</p>
<p class=definition>Example: Also allows : after definition.</p>
For the regex. ^ is the beginning of the string, [^:] matches everything not a colon +, for more than one match and ending with matching the colon itself, $& substitutes the match back in.
export const boldStringInAnotherString = (mainString, boldString) => {
const splitted = mainString.split(boldString)
return !mainString.includes(boldString) ? (<span>mainString</span>)
: (<span>{splitted[0]}<b>{boldString}</b>{splitted[1]}</span>)
}

Is it possible to replace a char by another with CSS?

My goal is to replace the display of _ by a blank space in my HTML document:
ex:
hello_world
should be
hello world
Possible Solutions:
Would be to create a
FONT that uses blank inside the _ character
Still looking for it!
Can this be done with CSS?
It is important that we do not modify the original string (we keep the _ character), but we simply display a blank space instead.
Regards
I think this is possible in CSS for a one-off kind of thing:
<span class="replace-me">hello_world</span>
.replace-me{
display:none;
}
.replace-me:after{
content:'hello world';
}
But I'm guessing that's not exactly what you want.
Otherwise, to replace all instances in JS:
document.body.innerHTML = document.body.innerHTML.replace('_', ' ');
You'll likely have to get a little more fancy with the regex but you could parse the page for underscores and wrap them in a <span>. Then use a pseudo element that has it's content set to a single space to replace the wrapped underscore.
<p>
Some_content with_underscores_going_on.
</p>
span:after {
font-size: 16px;
content: ' ';
}
span {
font-size: 0;
}
// jQuery
var f = $("body");
f.html( f.html().replace(/_/g,"<span>_</span>") );
jsFiddle: http://jsfiddle.net/h2h1bmyn/1/

Placing words directly under or above other words

I wish to do the following within div tags:
The words will be coloured differently using spans.
I will be given some text in a text box and via JavaScript I will need to dynamically update to div to show something like the above.
What is the best way to do this?
Will it involve a monospaced font?
Will it involve writing "hidden" text?
I wish to do entire paragraphs in this manner.
This might seem weird but the research I'm doing requires me present certain words from a given text with multiple colours and I think this might be a nice way of conveying this information.
Updating the text in the text box will update the following variables, and in turn I will need to convert these two variables into something like the image above.
text = "I am under the text above me and there is lots more text to come./n I am even moving onto a new line since I have more text"
color_per_word_position = {0:green, 1: red, 2: cyan, 4: yellow, 5: red, ...}
You will have to use a monospaced font for this.*
I basically see two options: 1. use whitespace 2. margins.
Option 1
Your text will look like
I•am•under•the•text•above
••am•under•••••text•above
where • denotes a space character. Pretty straight-forward in terms of CSS, since you don't have to worry about the spacing. The browser does it all for you. Example: http://jsfiddle.net/PYXdr/
*well, it may be possible with any font, using a lot of JS, but I guess it's not worth it.
Option 2
Since you probably don't want whitespace in between your spans, you may prefer this:
I•am•under•the•text•above
am•under text•above
Now, the spacing needs to be taken care of manually. Each span should get a margin-left that pushes it to the desired position. But before we can do that, we need to know the width of one character (using JS, since CSS does not provide that). Okay, pretty easy:
var el = document.createElement('pre');
el.style.display = 'inline-block';
el.innerHTML = ' ';
document.body.appendChild(el);
var width = parseFloat(getComputedStyle(el).width);
document.body.removeChild(el);
Now let's go ahead and move the spans:
span1.style.marginLeft = (2 * width) + 'px';
span2.style.marginLeft = (5 * width) + 'px';
Example: http://jsfiddle.net/JC3Sc/
Putting it all together
Now here's a basic example of how this might work:
var text = "I am under the text above me and there is lots more text to come.\nI am even moving onto a new line since I have more text"
var highlightBorders = [[2, 3, 4, 6], [6, 7]]; // YOUR TASK: implement the logic to display the following lines
var color_per_word_position = {0:'lime', 1: 'red', 2: 'cyan', 3:'orange', 4: 'yellow', 5: 'red'}
/* generate CSS */
var style = document.createElement('style');
for (var i in color_per_word_position) {
style.innerHTML += '.hl' + i + '{background:' + color_per_word_position[i] + '}';
}
document.head.appendChild(style);
/* generating the text */
text = text.split('\n');
var pre = document.createElement('pre');
text.forEach(function (line, i) {
var div = document.createElement('div');
var words = line.split(' ');
var result = [];
highlightBorders[i].forEach(function (len, j) {
var span = document.createElement('span');
span.innerHTML = words.splice(0, len).join(' ');
span.className = 'hl' + j;
if (j) {
span.style.marginLeft = width + 'px' // YOUR TASK: implement the logic
}
div.appendChild(span);
});
pre.appendChild(div);
});
document.body.appendChild(pre);
This is not a complete solution, since a) I don't really see which parts exactly you want to highlight and b) I don't want to spoil all the fun. But you get the idea.
Example: http://jsfiddle.net/tNyqL/
Using padding this is possible but also have absolute control by assigning text to a selector such as "p" for the class: fiddle http://jsfiddle.net/3NDs3/1/
.one {
width:200px;
}
.one p {
font: normal 14px Futura, sans-serif;
text-align:left;
padding-left:130px;
}
.two {
width:200px;
}
.two p {
text-align:center;
font: normal 14px Futura, sans-serif;
}
.three {
width:200px
}
.three p {
text-align:left;
font: normal 14px Futura, sans-serif;
padding-left:35px;
}
<div class="one">
<p>above me</p>
</div>
<div class="two">
<p>i am under the text above me</p>
</div>
<div class="three">
<p>under</p>
</div>

Change last letter color

Example code:
<p class="test">string</p>
I want to change the color on the last letter, in this case "g", but I need solution with css, I don't need a javascript solution.
I display the string letter by letter and i cant use static solution.
Everyone says it can't be done. I'm here to prove otherwise.
Yes, it can be done.
Okay, so it's a horrible hack, but it can be done.
We need to use two CSS features:
Firstly, CSS provides the ability to change the direction of the flow of the text. This is typically used for scripts like Arabic or Hebrew, but it actually works for any text. If we use it for English text, the letters are displayed in reverse order to how the appear in the markup. So to get the text to show as the word "String" on a reversed element, we would have to have markup that reads "gnirtS".
Secondly, CSS has the ::first-letter pseudo-element selector, which selects the first letter in the text. (other answers already established that this is available, but there's no equivalent ::last-letter selector)
Now, if we combine the ::first-letter with the reversed text, we can select the first letter of "gnirtS", but it'll look like we're selecting the last letter of "String".
So our CSS looks like this:
div {
unicode-bidi:bidi-override;
direction:rtl;
}
div::first-letter {
color: blue;
}
and HTML:
<div>gnirtS</div>
Yes, this does work -- you can see the working fiddle here: http://jsfiddle.net/gFcA9/
But as I say, it is a bit hacky. And who wants to spend their time writing everything backwards? Not really a practical solution, but it does answer the question.
Use ::after pseudo-element combined with attr() function:
p::after {
content: attr(data-end) ;
color: red ;
}
<p data-end="g">Strin</p>
p::after {
content: attr(data-end) ;
color: red ;
}
<p data-end="g">Strin</p>
Another solution is to use ::after
.test::after{
content: "g";
color: yellow;
}
<p class="test">strin</p>
This solution allows to change the color of all characters not only letters like the answer from Spudley that uses ::first-letter. See ::first-letter specification for more information. ::first-letter applies only on letters it ignores punctuation symbols.
Moreover if you want to color more than the last character you can :
.test::after{
content: "ing";
color: yellow;
}
<p class="test">str</p>
For more information on ::after check this link.
Without using javascript, your only option is:
<p class="test">strin<span class="other-color">g</span></p>
Edit for your fiddle link:
I'm not really sure why you said you didn't need a javascript solution, since you have quite a bit of it already. Regardless, in this example, you need to make only a couple small changes. Change line 10 from
elem.text(elem.text() + contentArray[current++]);
to
if ( current == contentArray.length-1 ) {
elem.html(elem.html() + "<span style='color:red'>"+contentArray[current++]+"</span>");
} else {
elem.html(elem.html() + contentArray[current++]);
}
Note that it's important to use .html() instead of .text() now, since there's actually HTML markup being inserted.
Working fiddle: http://jsfiddle.net/QTUsb/2/
It could be achieved using only CSS and an ::after pseudo-element without any changes in HTML:
.test {
font-size: 16pt;
position: relative;
}
.test::after {
bottom: 0;
color: red;
content: 'g';
position: absolute;
transform: translate(-100%, 0);
}
<p class="test">string</p>
In what way do you "display the string letter by letter"? If you're looping through the characters in a string (variable) you can certainly tell when you're at the last letter and wrap it in a whether doing so on the server side or client side.
Looking at the fiddles attached to another of your questions ...
If this is what you're talking about, you might have to set the .innerHTML of the element instead of the element.text()
From the fiddle at http://jsfiddle.net/SLKEn/ you would change it to something like this
if(current < contentArray.length) {
elem.html(
elem.html() +
(current == contentArray.length-1 ?
'<span class="lastchar">' + contentArray[current++] + '</span>' :
contentArray[current++])
);
}
along with CSS span.lastchar { color: red; }
Update: working fiddle based on your other question.
$(document).ready(function() {
var str=$("span").text();
strArr=str.split("");
for(var key=0;key<=strArr.length-1;key++) {
if(key==strArr.length-1) {
var newEle="<span id='lastElement'>"+strArr[key]+"</div>";
strArr[key]=newEle;
}
}
var newtext=strArr.join("");
$("span").html(newtext);
});
span#lastElement {
color: red;
}
i dont have the ability to comment on an answer thread but i wanted to point out an error in an answer provided by Marc_Alx that otherwise works wonderfully. that solution worked for me only after adding a semi-colon behind the content property... so it looks like content:"ing";
.test::after{
content:"ing";
color:yellow;
}
<p class="test">str</p>