使CSS伪元素:before的高度与主元素相同

21
我已经四处寻找,但自己无法找到解决方案。我正在尝试制作一个基本的可编辑代码编辑器,对于行号,我选择使用每行一个段落,并在CSS伪元素中设置计数器。
.editor {
  display: inline-block;
  border: 1px black solid;
  font-family: "Consolas", "Monaco", "Courier New", monospace;
  counter-reset: line;
  width: 90%;
  height: 350px;
  overflow: scroll;
  padding-left: 0;
  margin-left: 0;
  z-index: 1;
}

.editor p {
  display: block;
  counter-increment: line;
  background-color: #FFF;
  text-align: left;
  margin: 0px;
  z-index: 2;
  outline: none;
}

.editor p:before {
  display: inline-block;
  width: 2em;
  height: 100%;
  border-right: 1px black solid;
  padding-right: 1em;
  margin-right: 1em;
  content: counter(line);
  color: #FFF;
  background-color: #006;
  text-align: right;
  /*-webkit-user-select: none;
    user-select: none;*/
}
<div class="editor" contenteditable="true" spellcheck="false">
  <p>Some paragraph</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas aliquet nunc non pulvinar luctus. Cras finibus turpis at arcu mollis, nec fermentum mi pretium. Aliquam suscipit lacus sapien, eu fringilla enim malesuada quis. Sed ut tincidunt erat.
    In posuere vulputate venenatis. Mauris quis porta magna. Phasellus pharetra in nisl et luctus. Etiam in ultrices risus. Morbi vel dapibus ex. Suspendisse gravida libero non malesuada congue. Pellentesque ut nunc diam.</p>
  <p>&nbsp;</p>
  <p>&nbsp;</p>
  <p>&nbsp;</p>

</div>

问题在于,如果段落有点长,剩下的文本将会出现在我的计数器伪元素下面。我希望将:before计数器扩展到与段落相同的高度。

我尝试在段落上使用position:relative,并在p:before伪元素上使用position:absolute; height:100%,就像这里所解释的那样: 如何使伪元素检测非伪元素的高度?

在我的情况下,这种方法不起作用,因为我不希望p:before元素超过并覆盖段落,我只想要与当前行为相同,只是希望p:before元素以相同的高度延伸。

我也不希望这条线超过包装容器的宽度。我尝试了许多方法,但未能找到解决方案。


你应该在问题中展示你的HTML和CSS代码,以便需要时能够重现该问题。 - Jukka K. Korpela
我已经发布了一个 JSFiddle.... http://jsfiddle.net/zppb29jw/ 我认为这样更容易。 - just some guy
2
小提琴并不是代码的替代品,只是一种方便。一个问题应该在不跟随任何链接(可能会失效)的情况下被完全理解。 - Jukka K. Korpela
4个回答

49

不要使用height属性,而应该对p使用position: relative;,对:before使用position: absolute;

Js Fiddle

下面是新增加的CSS属性:

.editor p {
    position: relative;
    padding-left: 3.5em;


.editor p:before {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
 }

编辑

这应该是第二个问题 :D

在IE中按Enter键不会创建一个br,而在现代浏览器中,它会使用:after创建一个br。这里需要保证p标签不为空:

Js Fiddle

.editor {
  display: inline-block;
  border: 1px black solid;
  font-family: "Consolas", "Monaco", "Courier New", monospace;
  counter-reset: line;
  width: 90%;
  height: 350px;
  overflow: scroll;
  padding-left: 0;
  margin-left: 0;
  z-index: 1;
}
.editor p {
  display: block;
  counter-increment: line;
  background-color: #FFF;
  text-align: left;
  margin: 0px;
  z-index: 2;
  outline: none;
  position: relative;
  padding-left: 3.5em;
}
.editor p:before {
  display: inline-block;
  width: 2em;
  height: 100%;
  border-right: 1px black solid;
  padding-right: 1em;
  margin-right: 1em;
  content: counter(line);
  color: #FFF;
  background-color: #006;
  text-align: right;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  /*-webkit-user-select: none;
    user-select: none;*/
}
.editor p:after {
  content: " "
}
<div class="editor" contenteditable="true" spellcheck="false">
  <p>Some paragraph</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas aliquet nunc non pulvinar luctus. Cras finibus turpis at arcu mollis, nec fermentum mi pretium. Aliquam suscipit lacus sapien, eu fringilla enim malesuada quis. Sed ut tincidunt erat.
    In posuere vulputate venenatis. Mauris quis porta magna. Phasellus pharetra in nisl et luctus. Etiam in ultrices risus. Morbi vel dapibus ex. Suspendisse gravida libero non malesuada congue. Pellentesque ut nunc diam.</p>
  <p>one</p>
  <p>two</p>
  <p>three</p>
</div>


好的,像这样:http://jsfiddle.net/zppb29jw/3/ 看起来完全没有问题。我一直在尝试类似的东西,但是使用的是高度而不是上、下和左定位。谢谢! - just some guy
一如既往,IE毁了一切,在Chrome和Firefox中运行得很好,但是在IE中插入空行时它会消失。我知道可以编写一个JavaScript函数,在按下Enter键时添加文本节点,但这也会打开另一个潘多拉魔盒。尽量避免使用它... - just some guy
非常好!这实际上也解决了我的另一个问题,因为以前当你按下回车键并留空段落时,你无法选择该段落。这很奇怪,但昨晚我也尝试了使用after元素,猜想我太困了 :) 现在很酷,因为你可以在每行后面添加换行符号,就像这样: .editor p:after { content: "\21A9"; color:#CCC; } - just some guy
2022年的flex li 来说真是太好了,现在我只有在缩写id est时才会使用IE浏览器,而不是因为疼痛而昏厥和失去意识。 - Alan

2

由于您希望行号和行以表格方式显示,自然的方法是将它们制作成表格:将可编辑区域声明为表格(在CSS中),将行数设置为行,并将生成的行号设置为表格单元格:

.editor {
 display: tablek;
    border: 1px black solid;
    font-family: "Consolas", "Monaco", "Courier New", monospace;
    counter-reset: line;
 
 width:90%;
 height:350px;
 overflow:scroll;
 padding-left:0;
 margin-left:0;
 z-index:1;
 
}
.editor p {
 display: table-row;
    counter-increment: line;
 background-color:#FFF;
 text-align:left;
 margin:0px;
 z-index:2;
 outline: none;
 
}
.editor p:before {
 display: table-cell;
    width:2em;
 height:100%;
    border-right: 1px black solid;
    padding-right: 1em;
    margin-right: 1em;
    content: counter(line);
 color:#FFF;
 background-color:#006;
 text-align:right;
 
 /*-webkit-user-select: none;
    user-select: none;*/
}
<div class="editor" contenteditable="true" spellcheck="false">
<p>Some paragraph</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas aliquet nunc non pulvinar luctus. Cras finibus turpis at arcu mollis, nec fermentum mi pretium. Aliquam suscipit lacus sapien, eu fringilla enim malesuada quis. Sed ut tincidunt erat. In posuere vulputate venenatis. Mauris quis porta magna. Phasellus pharetra in nisl et luctus. Etiam in ultrices risus. Morbi vel dapibus ex. Suspendisse gravida libero non malesuada congue. Pellentesque ut nunc diam.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</div> 


这也很不错,但是IE会搞乱一些东西。你无法编辑段落中的文本。 - just some guy

0

http://jsfiddle.net/zppb29jw/2/

p {
    position:relative;
    left: 4em;
    ...

p:before {
    position:absolute;
    right:100%
    display:block;
    ...

这对你来说可以吗?


0
.black_right{
    position: relative;
    display: table;
    width: 100%;
    z-index: 10;
}
.black_right::after{
    content: " "; 
    top: 0px;
    height: 100%;
    width: 100%;
    box-shadow: 500px 0px #000;
    position: absolute;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接