admin管理员组

文章数量:1287956

I have requirement to highlight first character in each and every line, as example image below, all the content is in single paragraph, based on resolution change also it should behave same,

I have tried with flex box, and first child using script also, I could not able to find solution

Any help will be appreciated.

I have requirement to highlight first character in each and every line, as example image below, all the content is in single paragraph, based on resolution change also it should behave same,

I have tried with flex box, and first child using script also, I could not able to find solution

Any help will be appreciated.

Share Improve this question asked Jul 4, 2017 at 20:12 Naveen SettyNaveen Setty 6257 silver badges26 bronze badges 1
  • See github./xdamman/js-line-wrap-detector (referenced in stackoverflow./a/20956711/253973) - would need slightly extending to add an additional class to the first <span> of each line to be targetted via ::first-letter. Be wary of reflow if the paragraph isn't of a fixed width though. – Conan Commented Jul 4, 2017 at 21:05
Add a ment  | 

4 Answers 4

Reset to default 5

Try this:

p::first-letter {
  font-weight: bold;
  color: #8A2BE2;
}
<p>Hi there</p>
<p>Color first!</p>

EDIT: Ok, since you need this per each line in one paragrpah, you'll have to this with a script.

var allLines = document.querySelector("p").innerHTML.split("\n");
allLines = allLines.filter(function(x){return x !== ""}).map(function(x){
return "<span>" + x.charAt(0) + "</span>" + x.substr(1);
}).join("<br/>");
document.querySelector("p").innerHTML = allLines;
span {
  color: red;
}
<p>
TEXT
SOME MORE TEXT
</p>

CSS only responsive solution that uses mix-blend-mode, which is not supported by IE and Edge.

The idea is to use a colored overlay with a fixed width (the largest letter width) and mix-blend-mode: screen; to color only the 1st letter of each line.

You need to use a monospace font, so the color won't spill to the next letter if the 1st letter is narrow.

p {
  position: relative;
  font-family: monospace; /** to have constant character width **/
  font-size: 28px;
  background: white;
}

p::before {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  background: red;
  mix-blend-mode: screen;
  pointer-events: none; /** to enable selected of the text under the pseudo element **/
  color: transparent; /** to hide the character **/
  content: 'W'; /** a character in your font to use as width **/
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis euismod orci. Morbi ullamcorper augue ipsum, at consectetur turpis dictum sed. Phasellus bibendum tellus eu aliquet congue. Morbi ultrices aliquam purus, id semper diam aliquet eget. Nulla
  at tellus lacus. Curabitur massa lectus, auctor et lobortis vel, sodales non diam. Pellentesque gravida tortor ac ex porta congue. Ut vestibulum arcu ex, ac lacinia tortor pulvinar id. Nulla sagittis, lectus at luctus dignissim, orci nulla interdum
  ex, at euismod nibh ipsum et lacus. Suspendisse potenti. Quisque ac eros nunc. Suspendisse sit amet dolor diam. Phasellus blandit modo mi, at aliquam mi facilisis ut. Vestibulum lacinia enim tempor nunc elementum suscipit. Praesent ligula ipsum,
  venenatis et tellus at, imperdiet tempus lectus. Pellentesque consequat magna augue, at vestibulum sem facilisis nec.</p>

try this approach (probably not the best but it works just fine):

var content = document.getElementById('content').innerHTML
var doYourThing = function(){
  var formattedContent = content.replace(/(\w)/g,'<span>$1</span>')
  document.getElementById('formatted').innerHTML = formattedContent

  var characters = document.getElementsByTagName('span')
  var refPosition = characters[0].getBoundingClientRect().left

  for (character of characters){
    if(character.getBoundingClientRect().left <= refPosition){
      character.style.textTransform = "capitalize"
      character.style.color = "red"
    }
  }
}
doYourThing()
window.onresize = doYourThing
<p id="content">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque nisi minima veritatis ipsa magnam culpa ipsam dolores. Deserunt rerum, quod unde consequatur consectetur harum omnis sequi, voluptatum quaerat quasi illo?
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, esse, repellendus sed voluptate facere magni quis beatae corrupti odio id! Labore voluptatem soluta harum esse, at atque deserunt nesciunt ipsa.
</p>
<p id="formatted" style="background-color:#fee"></p>

Customize it to meet your needs. Good luck. JSFiddle

Easy way

An easy way to achieve this results is to split("\n") to get all lines, then replace the first letter of each line with itself, wrapped in a <span> with an appropriate class and finally join("<br/>") the lines and place them inside their original parent element.

var lines = document.querySelector("p").innerHTML.split("\n");
for(var key in lines)
 lines[key] = "<span class='first-letter'>" + lines[key].substr(0, 1) + "</span>" + lines[key].substr(1);
document.querySelector("p").innerHTML = lines.join("<br/>");
span.first-letter {
  font-weight: bold;
  color: red;
}
<p>This is a line 
This is another line 
This is yet another line</p>

Alternate (semantically correct) way

Another option is to split("\n") as before, but actually replace each line with itself wrapped in a <p> tag. Then join() the lines and replace the original parent with the lines themselves. This makes use of the ::first-letter CSS pseudo-element to style these classes and is more semantically correct than the previous one.

var lines = document.querySelector("p").innerHTML.split("\n");
for(var key in lines)
 lines[key] = "<p>" + lines[key] + "</p>";
document.querySelector("p").outerHTML = lines.join("");
p::first-letter {
  font-weight: bold;
  color: red;
}
/* This is a quick fix to make paragraphs display same as if the were all part of the same one, alter this based on your page's style and your needs. */
p + p {
  margin-top: -16px;
}
<p>This is a line 
This is another line 
This is yet another line</p>

本文标签: javascriptHighlight first character of every line using css or JSStack Overflow