Shortcode does not work, changes html order

the_post_thumbnail_url() will echo the URL. You should use functions that have get_the_... in the beginning of their names, since functions starting with the_... will generally echo the content.

So, your sprintf should use get_the_post_thumbnail_url() like this:

        $html .= sprintf(
            '<div class="grid-item"><a href="https://wordpress.stackexchange.com/questions/278102/%s" title="">%s</a></div>',
            get_the_post_thumbnail_url( get_the_ID(), 'full' ),
            the_title_attribute( 'echo=0' ),
            //get_the_title()
            //the_post_thumbnail()
        );

However, in this case the_title_attribute() doesn’t have a get_the_... version as far as I know. But you can disable the echo by passing it as an argument to the function.

Also, use wp_reset_postdata(); instead of wp_reset_query(). The latter should be used when you use query_posts() (which you shouldn’t use!).