Search code examples
cssmaterialize

Materialize helper text speech-bubble box arrow


I am am trying to create a live error box like this in Materialize CSS. I have currently got the box, but I cant work out how I would create the arrow.

This is what I currently have. https://codepen.io/anon/pen/jJmEKX

$(document).ready(function () {
        $("#password").on("keyup", function (e) {
            if ($("#password").val().length <= 8) {
                $(this).removeClass("valid").addClass("invalid");
            } else {
                $(this).removeClass("invalid").addClass("valid");
            }
        });
    });
input:not([type]).invalid ~ .helper-text:after, input:not([type]):focus.invalid ~ .helper-text:after, input[type=text]:not(.browser-default).invalid ~ .helper-text:after, input[type=text]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=password]:not(.browser-default).invalid ~ .helper-text:after, input[type=password]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=email]:not(.browser-default).invalid ~ .helper-text:after, input[type=email]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=url]:not(.browser-default).invalid ~ .helper-text:after, input[type=url]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=time]:not(.browser-default).invalid ~ .helper-text:after, input[type=time]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=date]:not(.browser-default).invalid ~ .helper-text:after, input[type=date]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=datetime]:not(.browser-default).invalid ~ .helper-text:after, input[type=datetime]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=datetime-local]:not(.browser-default).invalid ~ .helper-text:after, input[type=datetime-local]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=tel]:not(.browser-default).invalid ~ .helper-text:after, input[type=tel]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=number]:not(.browser-default).invalid ~ .helper-text:after, input[type=number]:not(.browser-default):focus.invalid ~ .helper-text:after, input[type=search]:not(.browser-default).invalid ~ .helper-text:after, input[type=search]:not(.browser-default):focus.invalid ~ .helper-text:after, textarea.materialize-textarea.invalid ~ .helper-text:after, textarea.materialize-textarea:focus.invalid ~ .helper-text:after, .select-wrapper.invalid ~ .helper-text:after {
    position: static;
    display: inline-block;
    content: attr(data-error);
    color: #FFF !important;
    padding: 15px;
    margin-top: 20px;
    background-color: #ee3224;
    border-radius: 6px;
    box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.06), 2px 2px 7px 0 rgba(0, 0, 0, 0.16);
    width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">


<div class="input-field password-padding">
   <input type="password" id="password" class="form-control" placeholder="Password" autocomplete="off" required="">
   <span class="helper-text" data-error="Passwords too short"></span>
   <label for="password" class="active input-center">Password</label>
</div>

And this is what I am wanting to end up with.

enter image description here

Does anyone know how I can add the arrow to the top of the box as per the example image?

Thanks


Solution

  • Firstly remove the display: inline-block; from your .helper-text::after and add these

    display: flex;
    align-items: center;
    

    Also margin-top: 10px; would be better than 20px

    And for triangle add these to your css file:

    input:not([type]).invalid ~ .helper-text::before, input:not([type]):focus.invalid ~ .helper-text::before, input[type=text]:not(.browser-default).invalid ~ .helper-text::before, input[type=text]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=password]:not(.browser-default).invalid ~ .helper-text::before, input[type=password]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=email]:not(.browser-default).invalid ~ .helper-text::before, input[type=email]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=url]:not(.browser-default).invalid ~ .helper-text::before, input[type=url]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=time]:not(.browser-default).invalid ~ .helper-text::before, input[type=time]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=date]:not(.browser-default).invalid ~ .helper-text::before, input[type=date]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=datetime]:not(.browser-default).invalid ~ .helper-text::before, input[type=datetime]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=datetime-local]:not(.browser-default).invalid ~ .helper-text::before, input[type=datetime-local]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=tel]:not(.browser-default).invalid ~ .helper-text::before, input[type=tel]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=number]:not(.browser-default).invalid ~ .helper-text::before, input[type=number]:not(.browser-default):focus.invalid ~ .helper-text::before, input[type=search]:not(.browser-default).invalid ~ .helper-text::before, input[type=search]:not(.browser-default):focus.invalid ~ .helper-text::before, textarea.materialize-textarea.invalid ~ .helper-text::before, textarea.materialize-textarea:focus.invalid ~ .helper-text::before, .select-wrapper.invalid ~ .helper-text:before {
          content: "";
          position: absolute;
          left: 10px;
          bottom: 100%;
          width: 0;
          height: 0;
          border-style: solid;
          border-width: 0 7px 7px 7px;
          border-color: transparent transparent #ee3224 transparent;
          transform: translateY(1px);
        }