This seems a known issue (see tracker), currently you need to sync the position yourself.
e.g.,
<zk>
<script><![CDATA[
function addSyncScroll (wgtId, parentId, add) {
var wgt = zk.Widget.$('#'+wgtId),
parentWgt = zk.Widget.$('#'+parentId);
if (wgt && parentWgt) {
var cbxToSync = parentWgt._cbxToSync,
idx;
if (!cbxToSync) {
initSyncScroll(parentWgt);
}
cbxToSync = parentWgt._cbxToSync;
if (cbxToSync) {
if (!wgt._syncPopupScroll) {
wgt._syncPopupScroll = function () {
zk(wgt.getPopupNode_()).position(wgt.getInputNode(), "after_start");
}
}
if (add) {
if (cbxToSync.indexOf(wgt) < 0)
cbxToSync.push(wgt);
} else {
if ((idx = cbxToSync.indexOf(wgt) < 0) > -1) {
cbxToSync.splice(idx, 1);
}
}
}
}
}
function initSyncScroll (parentWgt) {
parentWgt._cbxToSync = [];
parentWgt.$n().onscroll = function (event) {
var cbxToSync = parentWgt._cbxToSync;
for (var i = 0; i < cbxToSync.length; i++) {
cbxToSync[i]._syncPopupScroll();
}
}
}
]]></script>
<div width="200px" height="300px">
<div id="parent" width="100%" vflex="1" style="overflow:auto;">
<label value="Some text" />
<textbox value="01" />
<textbox value="02" />
<textbox value="03" />
<combobox>
<attribute name="onOpen"><![CDATA[
Clients.evalJavaScript("addSyncScroll('"+self.getUuid()+"', '"+parent.getUuid()+"', "+self.isOpen()+")");
]]></attribute>
<comboitem label="Simple and Rich" />
<comboitem label="Cool!" />
<comboitem label="Ajax and RIA" />
</combobox>
<textbox value="04" />
<textbox value="05" />
<textbox value="06" />
<textbox value="07" />
<textbox value="08" />
<textbox value="09" />
<textbox value="10" />
<textbox value="11" />
<textbox value="12" />
<textbox value="13" />
<textbox value="14" />
<textbox value="15" />
</div>
</div>
</zk>