How to remove empty flash box from a page?

So I encountered this problems many times before. By default those blue/red boxes around flash messages disappear when there’s no text inside. But this prevent any more fancy/more advanced UI to be created for flash messages. This peace of CSS makes sure that alert boxes disappear when there are no alerts. But when I run mix format then the code is formatted in a way that breaks those alert boxes.

.alert:empty {
  display: none;
}

I’ve tried to look here for an answer how I can handle flash messages especially in live views without those empty boxes. But I couldn’t find anything.

EDIT: Code below breaks flash messages.

While writing this I went through the source of live_flash/2 and I realized how to deal with that.

    <%= if not is_nil(@flash[:info]) do %>
      <p class="alert alert-info" role="alert" phx-click="lv:clear-flash" phx-value-key="info">
        <%= live_flash(@flash, :info) %>
      </p>
    <% end %>

You can check for flash in if before the alert block which makes it easy to do more fancy stuff with alerts. I wish this was in a autogenerated start app not the CSS magic we have now. I know designers might use it but this is more understandable for backend guys.

Small tip … It’s suggested to use unless condition instead of if not condition. :slight_smile:

Unfortunately the :empty pseudo class does not works how you think:

The :empty CSS pseudo-class represents any element that has no children. Children can be either element nodes or text (including whitespace). Comments, processing instructions, and CSS content do not affect whether an element is considered empty.

Although in CSS level 4 the definition was changed it’s still not supported …

Note: In Selectors Level 4, the :empty pseudo-class was changed to act like :-moz-only-whitespace, but no browser currently supports this yet.

Source of both information:

See also:

My best advice is to exclude messages from being formatted for now. Just add this to your .formatter.exs

  inputs:
    Enum.flat_map(
      ["*.{heex,ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{heex,ex,exs}"],
      &Path.wildcard(&1, match_dot: true)
    ) -- ["lib/myapp_web/templates/includes/flash.html.heex"],

This might have been fixed in the latest live view formatter. Changelog — Phoenix LiveView v0.17.10

There is also a new attribute phx-no-format which will skip formatting that element if present.