<div class='custom-textarea'>
    <textarea class='textarea'>Lorem ipsum dolor, sit amet consectetur
adipisicing elit. Perferendis, illo incidunt!
        
Tempore accusamus molestiae voluptatem nesciunt
eos doloremque perferendis maiores. Voluptas mollitia
velit exercitationem deserunt!
        
Repellendus sit iste quasi qui?
    
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Aliquid, rerum corporis deserunt nihil dolore recusandae
id labore consectetur odit itaque nesciunt possimus
fugiat aspernatur, eum sapiente quibusdam aut illo? Minus?

Lorem ipsum dolor sit amet consectetur adipisicing elit.
Numquam in dignissimos unde animi repudiandae inventore
modi ipsum quaerat ipsam deleniti provident ullam eius
porro distinctio fugiat, nam eveniet culpa magni.
</textarea>
    <div class='linenumbers'></div>
</div>
@import url('https://fonts.googleapis.com/css?family=Ubuntu+Mono');

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

::-moz-selection {
    background: #222725;
    color: #FFFFFF;
}

::selection {
    background: #222725;
    color: #FFFFFF;
}

body {
    overflow-x: hidden;
    background: #E4E6C3;
}

.custom-textarea {
    position: relative;
    width: 800px;
    max-width: 90%;
    margin: 20px auto;
    border-radius: 5px;
    box-shadow: 0 0 16px rgba(34, 39, 37, .3);
    overflow: hidden;

    &::after {
        content: '';
        display: block;
        position: absolute;
        top: 0;
        left: 42px;
        width: 16px;
        height: 100%;
        background: #FFFFFF;
        pointer-events: none;
        z-index: 1;
    }

    & > .textarea {
        display: block;
        position: relative;
        z-index: 1;
        width: calc(100% - 58px);
        height: 150px;
        min-height: 150px;
        max-height: 90vh;
        margin-left: 58px;
        font-size: 16px;
        line-height: 24px;
        font-family: 'Ubuntu Mono', monospace;
        outline: none;
        border: none;
        border-radius: 0 5px 5px 0;
        resize: vertical;
        white-space: pre;
        overflow: auto;
        word-wrap: normal;
        color: #121113;
        background: #FFFFFF;
    }

    & > .textarea::-webkit-scrollbar-track {
        border-radius: 0;
        background-color: #899878;
    }

    & > .textarea::-webkit-scrollbar {
        width: 12px;
        background-color: #FFFFFF;
    }

    & > .textarea::-webkit-scrollbar-thumb {
        border-radius: 0;
        background-color: #E4E6C3;
    }

    & > .linenumbers {
        position: absolute;
        top: 0;
        left: 0;
        width: 42px;
        background: #899878;
    }

    & > .linenumbers > .number {
        font-family: 'Ubuntu Mono', monospace;
        font-size: 16px;
        line-height: 24px;
        padding-left: 6px;
        color: #222725;
    }
}
View Compiled
class CustomTextarea {
    constructor(element) {
        this.element = element;
        this.textarea = this.element.querySelector('.textarea');
        this.numbers = this.element.querySelector('.linenumbers');
        
        this.numberOfNumbers = 0;

        this.addMoreNumbers();
        this.initEventListeners();
    }

    addMoreNumbers() {
        let html = '';

        for (let i = this.numberOfNumbers; i < this.numberOfNumbers + 100; i++) {
            html += `<div class='number'>${ i }</div>`;
        }

        this.numberOfNumbers += 100;
        this.numbers.innerHTML += html;
    }

    initEventListeners() {
        this.textarea.addEventListener('scroll', () => {
            this.numbers.style.transform = `translateY(-${ this.textarea.scrollTop }px)`;
            
            if (Math.abs(
                this.numbers.offsetHeight
                    - this.textarea.offsetHeight
                    - this.textarea.scrollTop) < 100) {
                this.addMoreNumbers();
            }
        });
    }
};

const textarea = new CustomTextarea(document.querySelector('.custom-textarea'));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.