HTML email not displaying properly in Gmail is usually Gmail doing what it is designed to do: sanitising the markup, dropping unsupported CSS, clipping long messages and holding images until the reader allows them.

None of that is a fault in your file. It is a different rendering target, and building for it is a separate discipline from building a web page.
HTML email not displaying properly in Gmail: what changes on the way in
| What you sent | What Gmail does | Consequence |
|---|---|---|
<style> block in the head |
Supported, but unsupported properties and selectors may be ignored | Parts of the styling drop out |
| External stylesheet | Not loaded | Same |
| Flexbox or grid layout | Not in Gmail's list of supported CSS properties | Columns may collapse into a stack |
| Long HTML body | Clipped past a size threshold | The end of the message is hidden |
| Remote images | Proxied, and may stay blocked | Empty boxes without alt text |
| Web fonts | Not loaded | Falls back to a default face |
An attached .html file |
Not rendered as the message body | Recipient has to open the file |
The clipping row is the one that surprises people, because the message looks complete in the sender's own sent folder.
Cause one: styles stripped
Gmail supports <style> blocks, but only a subset of CSS, and it may ignore properties and selectors outside that list. Other mail clients support less.
The common answer across clients is to put every declaration on the element itself.
<td style="padding:16px 24px;font:16px/1.5 Arial,sans-serif;color:#1a1a1a">
Quarterly summary
</td>
That is inline CSS, and it is the most portable styling across mail clients. It is also unpleasant to maintain by hand, which is why bulk senders generate it.
Cause two: the message is clipped
Past a size threshold, Gmail truncates the HTML and appends a View entire message link.
Everything after the cut is hidden unless the reader clicks through. If your unsubscribe line, your footer or your call to action is down there, it effectively does not exist.
Two mitigations. Keep the HTML small by removing comments, repeated inline declarations and unused markup, which is what minification does. And put what matters in the first screen rather than the last.
Cause three: images held back

Gmail serves images through its own proxy and may hold them until the reader chooses to display them. Some corporate setups never display them.
Write real alt text on every image, and make sure the message reads correctly with all images missing. A design that puts the headline inside an image disappears entirely.
Embedding pictures as base64 data URIs is not a way around this either. Support for data URIs in mail is inconsistent and it inflates the message toward the clipping threshold.
Cause four: it was an attachment, not a message body
If the recipient sees tags, you attached an .html file rather than sending HTML as the body.
Many mail clients do not render an attached HTML file inside the message, and some mail filters hold or remove HTML attachments.
Sharing an HTML file by email covers this case on its own.
The route that avoids all four
For a report, a dashboard, a proposal or an invitation, send a short message with a link.
- Check the page survives outside your folder. Drop it into the HTML file opener.
- Paste the HTML into a document. It renders as a page of its own, scripts and charts included.
- Create the share link. Share, then Share link, then Create share link. It is set to Anyone with the link by default.
- Send two lines and the link.

Nothing is stripped, because the mail carries no styling. Nothing is clipped, because the mail is short. Images appear, because they are on the page rather than in the message.
Marketing sends to a list, transactional receipts and newsletters genuinely belong in the inbox, and for those the table based, inline styled discipline is the price of entry.
Use a platform that generates that markup and tests it against real clients. Hand writing it for a one off internal message is effort spent on the wrong target.
For the decision in general, see email versus a link for documents and why links beat attachments. The same problems in a different client are in HTML not displaying correctly in Outlook.
Testing the message, not the file
Opening the HTML in a browser tells you nothing about how Gmail will render it, because the browser applies everything Gmail removes.
Send the message to yourself and read it in the web interface and in the phone app. Those two differ from each other often enough to be worth checking separately.
Then read it once with images turned off, because some recipients read mail that way.
Some mail apps adjust colours in dark mode, and a message that sets a background without setting a text colour can end up unreadable.
Set both together on every element that sets either. Do not rely on a light background being there.
Logos saved as flat images on white will show as white blocks, so use a transparent background or accept the box.
Everything above is effort spent on a rendering target you do not control. A link moves the content back into a browser, which you do.
Keep designed email for lists and receipts. For a report, a dashboard or an update to a handful of people, a two line message with an address is more reliable and stays correctable afterwards.