6

I'm trying to draw a textarea with alternate rows and line numbers. A very simple solution to have line numbers is the following - see here for more details.

textarea {
  background: url(http://i.imgur.com/2cOaJ.png);
  background-attachment: local;
  background-repeat: no-repeat;
  padding-left: 35px;
  padding-top: 10px;
  border-color: #ccc;
}
<textarea rows="10" cols="40"></textarea>

While to have a textarea with alternate rows is just a simple as

textarea {
  background-image: linear-gradient(#F1F1F1 50%, #F9F9F9 50%);
  background-size: 100% 4rem;
  border: 1px solid #CCC;
  width: 100%;
  height: 400px;
  line-height: 2rem;
  margin: 0 auto;
  padding: 4px 8px;
}
<textarea rows="10" cols="40"></textarea>

Both solutions works ok, but combining them it's tricky since both makes use of the background to hack the line numbers and the alternate rows background.

loretoparisi
  • 15,724
  • 11
  • 102
  • 146

2 Answers2

8

You could combine them by wrapping your textarea in a div then assign the stripped background styles to that wrapping div, so the 2 backgrounds are like layered.

textarea {
  background: url(http://i.imgur.com/2cOaJ.png);
  background-attachment: local;
  background-repeat: no-repeat;
  padding-left: 35px;
  padding-top: 10px;
  border-color: #ccc;

  font-size: 13px;
  line-height: 16px;
}

.textarea-wrapper {
  display: inline-block;
  background-image: linear-gradient(#F1F1F1 50%, #F9F9F9 50%);
  background-size: 100% 32px;
  background-position: left 10px;
}
<div class="textarea-wrapper">
  <textarea rows="10" cols="40"></textarea>
</div>

The wrapping div I set to display: inline-block so it wraps the textarea like an inline element and I positioned the background gradient 10px from the top to account for you padding-top.

You may have to play with the background size of the gradient to get it to properly match the line-height of the textarea.

UPDATE To @DavidThomas's point, to help line up your text with the alternating gradient the background-size height value should be 2 times the line-height of the textarea (see updated snippet). But the harder thing is to make it line up with the image numbers.

zgood
  • 12,181
  • 2
  • 25
  • 26
  • 1
    If you enter characters, and hit return for a new line, you'll see that the numbers don't line up with the line-height. You'll need to account for the the `
    ` and `
    – David Thomas Sep 17 '18 at 14:13
  • 1
    @DavidThomas See the update. The main issue is lining up everything with the image that has the numbers. But his question is regarding merging the image backgrounds... not lining up things exactly. – zgood Sep 17 '18 at 14:23
  • Any way to keep the lines lined up with the alternating background lines when scrolling vertically? – J. Scott Elblein Dec 28 '22 at 05:49
2

You could use multiple backgrounds for the same element.

CSS allows you to add multiple background images for an element, through the background-image property.


In you case:

textarea {
  width: 100%;
  min-height: 100px;
  background: url(http://i.imgur.com/2cOaJ.png) top -12px left / auto no-repeat, 
              linear-gradient(#F1F1F1 50%, #F9F9F9 50%) top left / 100% 32px;
  border: 1px solid #CCC;
  box-sizing: border-box;
  padding: 0 0 0 30px;
  resize: vertical;
  line-height: 16px;
  font-size: 13px;
}

body {
  margin: 0;
}
<textarea rows="10" cols="40"></textarea>
Quentin Veron
  • 3,079
  • 1
  • 14
  • 32
  • 1
    The problem with this approach is that after typing characters, hitting return for a new-line, and then continuing to type the user can only enter text on alternate line-numbers, which is a slightly odd user experience (https://i.stack.imgur.com/oeFYQ.png); also: the padding. :) – David Thomas Sep 17 '18 at 14:19
  • You're right. I was only providing here a solution for merging both images. – Quentin Veron Sep 17 '18 at 14:23