JSFiddle - React, Tailwind, and code Playground

HTML

<div class="scroller">
    <a href="#AX">A</a>
    <a href="#BX">B</a>
    <a href="#CX">C</a>
</div>
<div class="scroll-wrapper">
    <table>
        <tbody id="content">
        </tbody>
    </table>
</div>

CSS

.scroll-wrapper {
    max-height: 10em;
    position: relative;
    /* ha nincs js, akkor is lehessen scrollozni */
    overflow-y: scroll;
}

JavaScript

// setup, html gépelés helyett
function addRows(aNum) {
    for (var i = 0; i < aNum; ++i) {
        addRow(i+1, null);
    }
}
function addRow(aContent, aId) {
    $('#content').append('<tr><td' + (aId ? ' id="' + aId + '"' : '') + '>' + aContent + '</td></tr>');
}
function buildContent() {
    addRow('A', 'AX');
    addRows(50);
    addRow('B', 'BX');
    addRows(50);
    addRow('C', 'CX');
    addRows(50);
}
buildContent();

// lényegi működés

// saját görgetési mehanizmus előkészítése
$('.scroll-wrapper').css({overflow: 'hidden'});

// görgetés
$('.scroller').on('click', function ($e) {
    $e.preventDefault();
    var $scrollWrapper = $('.scroll-wrapper'),
        $target = $($e.target),
        $scrollTarget = $($target.attr('href')); // a link hivatkozásában tárolhatjuk a cél elem selectorját, és így még js nélkül is működik a betű szerinti görgetés
    
    console.log('scrollTop before', $scrollWrapper.scrollTop());
    // A jQuery offset() a dokumentumhoz képest számol, nem a scrollozási contextushoz
    console.log('$scrollTarget offset()', $scrollTarget.offset());
    // A standard CSSOM offsetTop adja a konzisztens választ
    console.log('scrollTarget offsetTop', $scrollTarget[0].offsetTop);
    
    $scrollWrapper.animate({scrollTop: $scrollTarget[0].offsetTop}, 500);
});