Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make CSS pseudoelement :before same height as main element

I've been looking all over and failed to find a solution to this on my own. I'm trying to make a basic contenteditable code editor, and for the line numbers I have chosen to use a paragraph for each line with a counter set in a CSS pseudo element.

.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>

The problem is that if the paragraph is a bit longer the rest of the text will go beneath my counter pseudoelement. I want to strech the :before counter to be the same height as the paragraph.

I have tried using position:relative on the paragraph and position:absolute; height:100% on the p:before pseudoelement like explained here: How can the pseudo element detect the height of the non-pseudo element?

This does not work in my case because I don't want the p:before element to go over and cover the paragraph, I just want the same behaviour as now, just want the p:before element to strech at the same height as the main p.

I also wouldn't want to have the line strech more than the width of the wrapper container. I've been trying many methods but failed to come to a solution.

like image 965
just some guy Avatar asked Oct 19 '14 10:10

just some guy


People also ask

Can I have multiple before pseudo-elements for the same element?

In CSS2. 1, an element can only have at most one of any kind of pseudo-element at any time. (This means an element can have both a :before and an :after pseudo-element — it just cannot have more than one of each kind.)

How do you use before and after pseudo-elements?

CSS ::before and ::after pseudo-elements allow you to insert “content” before and after any non-replaced element (e.g. they work on a <div> but not an <input> ). This effectively allows you to show something on a web page that might not be present in the HTML content.

When would you use the :: before or :: after pseudo element in your CSS?

In CSS, ::before creates a pseudo-element that is the first child of the selected element. It is often used to add cosmetic content to an element with the content property. It is inline by default.


2 Answers

Instead of height, rather use position: relative; for p, and position: absolute; for :before.

Js Fiddle

Here are the newly added CSS properties:

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


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

Edit

It should be a second question :D

Pressing Enter in IE will not create a br, whereas in modern browsers it creates a br using :after. Here is to guarantee so that p tag does not remain empty:

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>
like image 62
Vitorino fernandes Avatar answered Oct 09 '22 15:10

Vitorino fernandes


Since you want the line numbers and lines appear in table-like manner, the natural approach is to make them table: declare the editable area as table (in the CSS sense), make the lines rows, and make the generated line numbers table cells:

.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> 
like image 29
Jukka K. Korpela Avatar answered Oct 09 '22 15:10

Jukka K. Korpela