I am trying to style the first letter of a paragraph using CSS and wanted to add some animation using greensock, But actually the requirement is to style the each word's first letter not just the first letter paragraph.
Whats the suggestion/ideas on this?
p{
font-size:150%;
color:#000000;
}
p::first-letter {
font-size: 200%;
color: #ff0000;
}
<p>Hello This Is The Title</p>
UPDATE I tried handling the following way (adding span tag and targeting first element of each span) but it doesn't work:
p span:nth-child(1)::first-letter {
font-size: 200%;
color: #ff0000;
}
use with split(" ") for create the array form string and forEach() is iterate the each word. Then slice(0,1) the cut first letter of the word then append with span .And add the css effect with span
var str = $('p').text().split(" ");
$('p').empty();
str.forEach(function(a) {
$('p').append(' <span>' + a.slice(0, 1) + '</span>' + a.slice(1))
})
p {
font-size: 150%;
color: #000000;
}
span {
font-size: 200%;
color: #ff0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Hello This Is The Title</p>
const p = document.getElementById('text')
const styleMe = l => '<span class="styled">' + l + '</span>'
const newS = p.innerText.split(' ').map(w => w.split('').map((l,i) => (i === 0) ? styleMe(l) : l).join('')).join(' ')
p.innerHTML = newS
.styled {
color:red
}
<p id="text">Hello This Is The Title</p>
There is no css first-word css selector. So you can use jquery to achieve this.
Solution 1: To style only 1st word of a paragraph .
$(function() {
$('p').each(function() {
var text = this.innerHTML;
var firstSpaceIndex = text.indexOf(" ");
if (firstSpaceIndex > 0) {
var substrBefore = text.substring(0,firstSpaceIndex);
var substrAfter = text.substring(firstSpaceIndex, text.length)
var newText = '<span class="firstWord">' + substrBefore + '</span>' + substrAfter;
this.innerHTML = newText;
} else {
this.innerHTML = '<span class="firstWord">' + text + '</span>';
}
});
});
.firstWord{ color:red; font-size:20px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Styling the first word of pragraph.</p>
Solution 2 : Too style each first letter of paragraph line
$(document).ready(function() {
var words = $('p').text().split(' ');
var html = '';
$.each(words, function() {
html += '<span class="firstLetter">'+this.substring(0,1)+'</span>'+this.substring(1) + ' ';
});
$('p').html(html);
});
.firstLetter{ color:red; font-size:20px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Styling each first letter of the word in pragraph.</p>
What you are looking for is a pseudo-element that doesn't exist. There is :first-letter and :first-line, but no :first-letter-every-word.
The easiest option would be to wrap the first letter of each word in a <span>. Another option would be to try a javascript solution.
Related
I would like to know how I can give highlight on any letter and if there is a space after or before the word it doesn't eat the space...
function highlight(text) {
const InputsTexts = document.querySelectorAll('.item-question-faq');
for (const inputText of InputsTexts) {
let innerHTML = inputText.innerHTML;
let index = innerHTML.toUpperCase().indexOf(text.toUpperCase());
if (index !== -1) {
innerHTML = innerHTML.substring(0, index) + "<span class='highlight'>" + innerHTML.substring(index, index + text.length) + '</span>' + innerHTML.substring(index + text.length);
inputText.innerHTML = innerHTML;
}
}
}
document.body.onload = function() { highlight('order'); };
.item-question-faq {
display: flex;
margin-left: 5px;
align-items: center;
font-size: 14px;
margin-left: 3px;
margin-right: 3px;
}
.highlight {
background: yellow;
}
<p class="item-question-faq webrep-faq" >the order is important</p>
Here is a printout of how it looks when applying the highlight
the application can't use Jquery or libraries
how can i solve this?
This is because you've set the parent element (paragraph) to display: flex. Part of what a flexbox does is decide how to pack in the children elements, and how much space to add between them.
It is almost certainly a mistake to use display: flex for an element that directly contains raw text. Usually, flexboxes are wrapper elements that contain discrete blocks of content.
If you remove this property, allowing the paragraph to use its native display: block mode, the spaces will be preserved as you expected.
function highlight(text) {
const InputsTexts = document.querySelectorAll('.item-question-faq');
for (const inputText of InputsTexts) {
let innerHTML = inputText.innerHTML;
let index = innerHTML.toUpperCase().indexOf(text.toUpperCase());
if (index !== -1) {
innerHTML = innerHTML.substring(0, index) + "<span class='highlight'>" + innerHTML.substring(index, index + text.length) + '</span>' + innerHTML.substring(index + text.length);
inputText.innerHTML = innerHTML;
}
}
}
document.body.onload = function() { highlight('order'); };
.item-question-faq {
margin-left: 5px;
align-items: center;
font-size: 14px;
margin-left: 3px;
margin-right: 3px;
}
.highlight {
background: yellow;
}
<p class="item-question-faq webrep-faq" >the order is important</p>
minor tip: you can use javascript's forEach to make your code just a little more concise.
Instead of:
const InputsTexts = document.querySelectorAll('.item-question-faq');
for (const inputText of InputsTexts) {
/* do stuff */
}
Consider:
document.querySelectorAll('.item-question-faq').forEach((inputText) => {
/* do stuff */
});
I have this code:
<div id="ce" contenteditable>I love me some foo bar and shit.</div>
<p>
clear
</p>
<script>
var changed, lastValue = '', div = $('#ce'), words = [ 'oele', 'geel',
'politie', 'foo bar' ];
function markWords() {
var html = div.html().replace(/<\/?strong>/gi, ''), text = html
.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' '), exp;
$.each(words, function(i, word) {
exp = new RegExp('\\b(' + word + ')\\b', 'gi');
html = html.replace(exp, function(m) {
console.log('WORD MATCH:', m);
return '<strong>' + m + '</strong>';
});
});
//html = html.replace(' ', ' ').replace(/\s+/g, ' ');
console.log('HTML:', html);
console.log('----');
div.html(html);
}
setInterval(function() {
var html = div.html();
if (lastValue != html && html) {
//console.log(lastValue);
//console.log(html);
//console.log('----');
lastValue = html;
markWords();
setEndOfContenteditable(div[0]);
}
}, 500);
function setEndOfContenteditable(contentEditableElement) {
var range, selection;
if (document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
{
range = document.createRange();//Create a range (a range is a like the selection but invisible)
range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
selection = window.getSelection();//get the selection object (allows you to change selection)
selection.removeAllRanges();//remove any selections already made
selection.addRange(range);//make the range you have just created the visible selection
} else if (document.selection)//IE 8 and lower
{
range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
}
}
</script>
<style>
[contenteditable] {
padding: 10px;
border: dotted 1px #aaa;
}
[contenteditable]>div {
margin: 10px 0;
}
[contenteditable] strong {
font-weight: normal;
background: red;
color: white;
}
</style>
http://jsfiddle.net/nebgcpzz/
What it does is that it gets specific words and puts red background on them. But when you put cursor in middle or anywhere (but the end) and type 1 character, cursors jumps forward. Any taughts?
I need help with optimizing this small system that takes in a string and looks for any words that match the words stored in an array. The system should reprint the same string with the new words every time there was a match. However, it only changes after the first match currently.
Sample text:
his de is good
but his en is worse then nl
The result for the above is currently:
his Dutch is good
but his English is worse then nl
But the result I want to get is:
his Dutch is good
but his English is worse then Danish
So how can I fix the system to print the second result?
Here is my system in JSFIDDLE.
function check(string, wrapper) {
var terms = ['de', 'en', 'nl'];
var match = false;
for(var i=0;i<terms.length && !match;i++) {
if(string.indexOf(terms[i]) > -1) {
match = true;
var newString='';
wrapper.css("background", "#a1e4ff");
var matchString = string.substring(string.indexOf(terms[i]), (string.indexOf(terms[i])+terms[i].length));
var rx = RegExp("\\b" + matchString + "\\b", "g");
switch(matchString) {
case 'de':
newString = string.replace(rx, "Dutch");
break;
case 'en':
newString = string.replace(rx, "English");
break;
case 'nl':
newString = string.replace(rx, "Danish");
break;
default:
alert('no matches');
}
$(".corrections").append("<li>" + newString + "</li>");
}
}
}
$(document).ready(function() {
$('textarea').focusout(function() {
var x = $(this).val();
$('.orig-list').html(x.replace(/\n(?!>)/g, '<li>'));
});
$('#down').click(function() {
$('.orig-list li').each(function() {
var phrase = $(this).text();
var matchHighlight = $(this);
check(phrase, matchHighlight);
});
});
});
The main point is that you did not add <li> tag before the first item, and that is why you $('.orig-list li').each did not select it and that is why the string consisting of one line did not work. Change the $('.orig-list').html() code to
$('.orig-list').html("<li>" + x.replace(/\n(?!>)/g, '<li>'));
Besides, it will be much easier if you put the terms with replacements into a dictionary, and use it like
if (/en|de|nl/.test(string)) {
wrapper.css("background", "#a1e4ff");
newString = string.replace(/en|de|nl/g, function(x) {
return terms[x] || "";
});
$(".corrections").append("<li>" + newString + "</li>");
}
See the updated snippet below.
function check(string, wrapper) {
var terms = {'de':'German', 'en':'English', 'nl':'Dutch'};
if (/en|de|nl/.test(string)) {
wrapper.css("background", "#a1e4ff");
newString = string.replace(/en|de|nl/g, function(x) {
return terms[x] || "";
});
$(".corrections").append("<li>" + newString + "</li>");
}
}
$(document).ready(function() {
$('textarea').focusout(function() {
var x = $(this).val();
$('.orig-list').html("<li>" + x.replace(/\n(?!>)/g, '<li>'));
});
$('#down').click(function() {
$('.orig-list li').each(function() {
var phrase = $(this).text();
var matchHighlight = $(this);
check(phrase, matchHighlight);
});
});
});
span#down {
background: #4f5152;
width: 100px;
color: #fff;
display: block;
margin-top: 20px;
padding: 9px;
border-radius: 4px;
line-height: 1;
font-weight: 600;
cursor:pointer;
margin-bottom: 50px;
}
.receiver div {
border: 1px solid red;
width: 40%;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content-wrapper">
<div class="receiver">
<textarea></textarea>
<span id="down">Generate List</span>
<div>
<h4>Generated List with unicode errors</h4>
<ol class="orig-list"></ol>
</div>
<div class="corrections-wrapper">
<h4>Corrected Names</h4>
<ol class="corrections"></ol>
</div>
</div>
</div>
I'm using a word count textarea jquery script and I'm trying to work out how to update the word count onload to e.g. 2 from the preset text area "this example" to start with.
(it currently shows 0)
I can set the focus on it and move the cursor but I don't know how to update it initially, any ideas?
HTML
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="js/jQuery.textareaCounter.c.js"></script>
<textarea id="txtarea" name="text" rows="7" cols="120">this example</textarea>
<script type="text/javascript">
$("textarea").textareaCounter();
document.getElementById('txtarea').focus();
var val = document.getElementById('txtarea').value; //store the value of the element
document.getElementById('txtarea').value = ''; //clear the value of the element
document.getElementById('txtarea').value = val; //set that value back. so cursor is at end.
</script>
jquery.min.js contains:-
(function(a){a.fn.textareaCounter=function(b){var c={limit:10};var b=a.extend(c,b);return this.each(function(){var c,d,e,f;c=a(this);c.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">Max. '+b.limit+" words</span>");c.keyup(function(){d=c.val();if(d===""){e=0}else{e=a.trim(d).split(" ").length}if(e>b.limit){a("#counter-text").html('<span style="color: #DD0000;">0 words left</span>');f=a.trim(d).split(" ",b.limit);f=f.join(" ");a(this).val(f)}else{a("#counter-text").html(b.limit-e+" words left")}})})}})(jQuery)
jQuery.textareaCounter.c.js contains:-
(function(a) {
a.fn.textareaCounter = function(b) {
var c = {
limit: 10
};
var b = a.extend(c, b);
return this.each(function() {
var c, d, e, f;
c = a(this);
c.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">' + "0 words</span>");
c.keyup(function() {
d = c.val();
if (d === "") {
e = 0
} else {
e = d.replace(/^[\s,.;]+/, "").replace(/[\s,.;]+$/, "").split(/[\s,.;]+/).length;
}
if (e > b.limit) {
// a("#counter-text").html('<span style="color: #DD0000;">0 words left</span>');
// f=a.trim(d).split(" ",b.limit);
// f=f.join(" ");
// a(this).val(f)
a("#counter-text").html(e + " words ")
document.myform.numwords.value = e;
} else {
a("#counter-text").html(e + " words ")
document.myform.numwords.value = e;
}
});
});
}
})
(jQuery)
This is what I changed in jQuery.textareaCounter.c.js:
var initCount = c.text().split(" ").length;
if(initCount < 2){initCount=0;}
c.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">' + initCount +" words</span>");
Here is the JSFiddle demo
You can fire a keyup event during initialization to trigger the update:
<script type="text/javascript">
$("textarea").textareaCounter();
document.getElementById('txtarea').focus();
var val = document.getElementById('txtarea').value; //store the value of the element
document.getElementById('txtarea').value = ''; //clear the value of the element
document.getElementById('txtarea').value = val; //set that value back. so cursor is at end.
// init word count
$("textarea")[0].dispatchEvent(new Event('keyup'));
</script>
//Function to show maxlength of Textarea
document.getElementById("textArea").addEventListener("keyup",function(){
var textAreaValue = document.getElementById("textArea").value;
var show = (250 - (textAreaValue.length));
document.getElementById('count').innerHTML = show + " characters remaining";
});
I need to truncate the text(with ... at the end) and on mouseover the entire text should get expanded.
I have tried to truncate by the below code. Problem with this code is, it expands the content on click of the ... but I need it to get opened when user mouse over anywhere on p tag
var len = 100;
var p = document.getElementById('truncateMe');
if (p) {
var trunc = p.innerHTML;
if (trunc.length > len) {
trunc = trunc.substring(0, len);
trunc = trunc.replace(/\w+$/, '');
trunc += '<a href="#" ' +
'onmouseover="this.parentNode.innerHTML=' +
'unescape(\''+escape(p.innerHTML)+'\');return false;">' +
'...<\/a>';
p.innerHTML = trunc;
}
}
DEMO
I am looking for an easy way to do it.
Thanks in advance.
PS: No CSS solution please, as it is not compatible with all browsers (IE7).
You can use Jquery Like this :
HTML :
<p>Some Text</p>
JS :
var lengthText = 30;
var text = $('p').text();
var shortText = $.trim(text).substring(0, lengthText).split(" ").slice(0, -1).join(" ") + "...";
$('p').text(shortText);
$('p').hover(function(){
$(this).text(text);
}, function(){
$(this).text(shortText);
});
DEMO : http://jsfiddle.net/1yzzbv4b/2/
Or you can also achieve this with css3 property text-overflow:ellipsis;
CSS :
p{
text-overflow:ellipsis;
width: 250px;
white-space: nowrap;
overflow: hidden;
}
p:hover{
text-overflow:clip;
width:auto;
white-space: normal;
}
DEMO : http://jsfiddle.net/1yzzbv4b/
Assuming that you set the class of your p-elements to be of escape-text, the following jQuery-code should work.
$(document).ready(function() {
$ps = $('.escape-text');
$ps.each(function(i, el) {
$(el).data('full-text', el.innerHTML);
strip(el);
});
$ps.on('mouseover', function() {
$(this).text($(this).data('full-text'));
}).on('mouseout', function() {
$(this).text(strip(this));
})
});
var length = 100;
var strip = function(el) {
el.innerHTML = el.innerHTML.substr(0, length) + '...';
}