The following is primarily not an answer, more an extended comment
As noted in the comments under @samcarter's answer, I wrote a package which does shift the accents placed with \mathaccentV
(which is part of amsmath
) based on the height of the contents it is used on. This does improve the placement of the accents for most cases. The patch is engine independent but there certainly are better approaches (e.g., what beamer
does when used with its standard fonts and pdfTeX). Also the patch can be used with different fonts and the placement can be adjusted.
You'll need the package which is not published on CTAN, but hosted here: MRTsfacc. It also needs the package MRTif. Documentation for both packages is available in this PDF. The packages are part of my MRTbundle
which I wrote as a template for the institute where I wrote my bachelor's thesis.
The following is a comparison which is also included in the documentation of MRTsfacc
(font in use is helvet
with mathastext
loaded with the options italic
and defaultmathsizes
; compiled with pdfTeX):

Usage with the two packages above installed (I don't have Arial, so I used DejaVu Sans; compiled with XeTeX):
\documentclass{article}
\usepackage[no-math]{fontspec}
\setsansfont{DejaVu Sans}
\usepackage[]{amsmath} % not necessarily needed, MRTsfacc loads amsmath with \RequirePackage
\renewcommand{\familydefault}{\sfdefault}
\usepackage{MRTsfacc}
% if the used shift isn't just right you can use the following to redefine the
% width
\MRTsfaccSet{.22} % default is .25
\usepackage[italic]{mathastext}
\newcount\foocount
\begin{document}
\Huge\noindent
a e f 1 2 3 \\ $\hat{a} e f 1 2 3$
% a loop creating every upper case letter in a \hat
\foocount65
\loop\ifnum\foocount<91
% using \hat* results in a \hat with the accent moved regardless of the
% argument, this is used as the test to see whether the argument is a letter
% does fail for \char\foocount
$\hat*{\char\foocount}$
\advance\foocount1
\repeat
% a loop creating every lower case letter in a \hat
\foocount97
\loop\ifnum\foocount<123
$\hat*{\char\foocount}$
\advance\foocount1
\repeat
\end{document}
The package does only automatically apply the shift, if the argument to such macros using \mathaccentV
internally is a letter (so has catcode 11). You can enforce the shift with a *
after the macro, or disallow such shift with !
, so \hat*
always uses the shift, \hat!
never does.
Results of above code:
