如何选择第 n 行文本 (CSS/JS)

IT技术 javascript html css css-selectors
2021-01-18 03:27:25

如何在特定文本行上选择和应用样式?CSS 伪元素 :first-line,但我想选择任何行,不限于第一行。

似乎仅使用 CSS 无法完成...无论如何我不介意使用 JS 解决方案。


更新:

嗯,其实只是为了兴趣。我正在尝试实现诸如突出显示段落的每一行(为了可读性,就像每个人对表格行所做的那样)...

预先格式化文本,如:

<p>
<span class='line1'>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do </span>
<span class='line2'>eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad </span>
<span class='line3'>minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip </span>
<span class='line4'>ex ea commodo consequat. Duis aute irure dolor in reprehenderit in </span>
<span class='line5'>voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur </span>
<span class='line6'>sint occaecat cupidatat non proident, sunt in culpa qui officia </span>
<span class='line7'>deserunt mollit anim id est laborum.</span>
</p>

...对我来说没问题,但如何知道在哪里拆分?即使给出了段落的宽度,仍然很难确定......

5个回答

有趣的。你可以用 JavaScript 做类似的事情:

$(function(){ 
  var p = $('p'); 
  var words = p.text().split(' '); 
  var text = ''; 
  $.each(words, function(i, w){
                   if($.trim(w)) text = text + '<span>' + w + '</span> ' }
        ); //each word 
  p.html(text); 
  $(window).resize(function(){ 

    var line = 0; 
    var prevTop = -15; 
    $('span', p).each(function(){ 
      var word = $(this); 
      var top = word.offset().top; 
      if(top!=prevTop){ 
        prevTop=top; 
        line++; 
      } 
      word.attr('class', 'line' + line); 
    });//each 

  });//resize 

  $(window).resize(); //first one
});

基本上,我们用一个跨度包裹每个单词,并在窗口调整大小时根据跨度的位置添加一个类。我相信它可以更有效地完成,但它可以作为概念证明。当然,对于偶数/奇数行,您可以简化代码。

边缘情况:我没有在类改变单词大小或宽度的地方测试它。它最终可能会非常错误。

这是在行动:https : //jsbin.com/piwizateni/1/edit?html,css,js,output

很好的解决方案 :) 但是如果我们想在段落中保留额外的标记怎么办?我的意思是在您的代码的第 3 行中,text()将删除段落中<span><strong>段落内的html 标签
2021-03-19 03:27:25
谢谢安迪!正如我所说,这与生产代码相去甚远。使用这种方法,您必须将单词与每个子标签分开(或忽略它),然后获取自由文本节点(没有父标签的文本 - 如stackoverflow.com/questions/992472#992568 中所示)。我们可以text单独使用它们中的每一个,并保留标记。需要考虑一下,因为我确信还有更多的边缘情况(事实上,大多数情况在这里不起作用,所以我的代码是针对边缘情况的!)。
2021-03-24 03:27:25

如果每一行都是单独的,<li>或者<p>您可以使用 CSS 选择它。

:nth-child(N)

取自sitepoint.com,适用于 Opera 9.5+、Safari 4+、FF3.5+

描述

这个伪类根据元素在父元素的子元素列表中的位置来匹配元素。伪类接受一个参数 N,它可以是关键字、数字或 an+b 形式的数字表达式。有关更多信息,请参阅了解:nth-child伪类表达式。

如果 N 是数字或数字表达式, :nth-child(N) 匹配文档树中 N-1 个兄弟元素之前的元素。

以下示例选择器是等效的,将匹配奇数表行:

tr:nth-child(2n+1) {
  ⋮ declarations
}
tr:nth-child(odd) {
  ⋮ declarations
}

此示例选择器将匹配任何表的前三行:

tr:nth-child(-n+3) {
  ⋮ declarations
}

此示例选择器将匹配作为其父元素的第一个子元素的任何段落:

p:nth-child(1) {
  ⋮ declarations
}

这当然等同于选择器 p:first-child。

例子

此示例选择器将匹配奇数表行:

tr:nth-child(odd) {
  ⋮ declarations
}

您也可以使用jQuery

如果有人感兴趣,我找到了一个名为lining.js的 JavaScript 库来帮助解决这个问题。它启用了这样的 CSS 语法:

<style>
  .poem .line[first] { /* `.poem::first-line`*/ }
  .poem .line[last] { /* `.poem::last-line` */ }
  .poem .line[index="5"] { /* `.poem::nth-line(5)` */ }
  .poem .line:nth-of-type(-n+2) { /* `.poem::nth-line(-n+2)` */ }
  .poem .line:nth-last-of-type(2n) { /* `.poem:::nth-last-line(2n)` */ }
</style>

( GitHub )

如果我们将其限制为文本和背景颜色,则可以使用 CSS 实现此效果:

body {
  font-size: 16px;
  line-height: 20px;
}

.text {
  background: linear-gradient(to bottom, crimson 20%, coral 20% 40%, seagreen 40% 60%,
                              dodgerblue 60% 80%, mediumslateblue 80%);
  background-size: 100px 100px;
  background-position: top left;
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}

.background {
  background: linear-gradient(to bottom, white 50%, #eee 50%);
  background-size: 100px 40px;
  background-position: top left;
}
<div class="background">
  <div class="text">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sagittis nunc non nisi venenatis auctor. Aliquam consectetur pretium sapien, eget congue purus egestas nec. Maecenas sed purus ut turpis varius dictum. Praesent a nunc ipsum, id mattis odio.
    Donec rhoncus posuere bibendum. Fusce nulla elit, laoreet non posuere ac, pharetra id justo. Mauris odio est, imperdiet eget sollicitudin non, aliquet in nulla. Aliquam erat volutpat. Pellentesque bibendum tellus nibh. Ut consequat sem sit amet quam
    tristique ut tempor massa rhoncus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sagittis nunc non nisi venenatis auctor. Aliquam consectetur pretium sapien, eget congue purus egestas nec. Maecenas sed purus ut turpis varius dictum.
    Praesent a nunc ipsum, id mattis odio. Donec rhoncus posuere bibendum. Fusce nulla elit, laoreet non posuere ac, pharetra id justo. Mauris odio est, imperdiet eget sollicitudin non, aliquet in nulla. Aliquam erat volutpat. Pellentesque bibendum tellus
    nibh. Ut consequat sem sit amet quam tristique ut tempor massa rhoncus.
  </div>
</div>

  • 首先,我们创建一个backgroundusing linear-gradient,来实现条纹效果
  • 我们设置line-height20px在此,这将简化例子。
  • 我们要确保背景和文本行对齐,因此我们设置了background-size. 如果我们有 5 条颜色,每条线都是20px,背景高度应该是100px(宽度在这里无关紧要)。
  • 最后,为了给字母而不是背景着色,我们使用了一个相对较新的 CSS 属性 - background-size这会以与文本内容相同的形状绘制背景。我们仍然需要设置,color: transparent因为没有它,文本仍然在背景上涂成黑色。

如果我理解正确,您希望能够通过 CSS 将样式应用于文档中的特定行。例如:使第 5 行加粗。

这是不可能的 - CSS 不是面向行的,而是面向 DOM 元素的。因此,要实现您的目标,您必须将您的线条包裹在 <span>(或 <div>)元素中,然后将样式应用于该元素。

CSS 不是面向行的,因为行号是虚幻的:行号会根据屏幕分辨率、浏览器窗口的宽度、浏览器中定义的默认字体等而变化。因此,基于行号的样式会给您带来可疑的结果.

CSS 确实有一个::first-line伪元素。
2021-03-27 03:27:25