varioref can in fact do this you just need to give its \vpageref command a hint what to write to refer to an element on the same page. From the documentation:
But in fact \vpageref allows even more control. If has two optional arguments.
With the first one, one can specify the text that should be used if label and reference fall on the same page. This is very helpful if both are near to each other, so that they may or may not be separated by a page break. In such a case we usually know (!) whether the reference is before or after the label so that we can say something like
... see the example \vpageref[above]{ex:foo} which shows ...
which will then come out as “. . . see the example above which shows . . . ”
The point is that if there is a page break in between the label and the element, \vpageref will notice this and insert something like on the previous page instead.