If we figured out the best practice for common GUI cases (ex. in tables, shade every other row light gray), you could hide the complexity from the average program writer and make better decisions for them.
A GUI toolkit is already a set of best practices. Designing one is a difficult matter of balancing convenience with flexibility. Make it too basic and you complicate special cases and impede innovation. Make it too detailed and you force noisy code and wheel reinvention.
Right. I think that's why good toolkits have good default behaviors that you can also easily overwrite through well documented APIs. I think a good abstraction should let you also access the underlying layer for special cases.
An API designed for overriding still suffers from the same compromise. Any particular use case will want to override a specific set of functionality and nothing more. More fine grained overridability means more overhead complexity. Simplicity means you have to override functionality in large units, likely reimplementing most of it.