Only with CSS is there any way to make a "Toast"? An element that goes up and then click to close it?

Asked

Viewed 666 times

8

In mobile there is a very common component that is known as "Toast", but I kept thinking about how to adapt it only with HTML and CSS

toa

Is there any way to do something like this "component" above just using CSS and HTML, without framework or other libraries?

I arrived at this model below, but I would like to make it functional like these alerts of the kind "Toast" that we see mainly on Android...

How to make it go up and stand still, and then click on the X to close it?

.btn {
    background-color: purple;
    border-radius: .5em;
    box-shadow: 0 .25em .5em 0 rgba(0, 0, 0, .25);
    padding: 1em;
    color: #fff;
    text-transform: uppercase;
    font-family: sans-serif;
    font-weight: bold;
    border: none;
    cursor: pointer;
    transition: background-color 250ms;
}
.btn:hover {
    background-color: rgb(100, 0, 100);
}
.toast {
    position: fixed;
    display: flex;
    bottom: 0;
    left: 0;
    width: 100%;
    justify-content: space-between;
    background-color: rgb(100, 0, 100);
    font-family: sans-serif;
}
.toast p,
.toast a {
    color: #fff;
    margin: 0;
    padding: 2em;
    text-decoration: none;
}
<br>
<label class="btn" for="open">TOAST</label>
<br>
<div class="toast">
    <p>
        Lorem, ipsum dolor.
    </p>
    <a href="#">
        X
    </a>
</div>

  • So in this case it is necessary to use javascript to manipulate these events and make the change in CSS, I will make an example

  • @Taciiobrito I know that with JS or jQuery is possible, but my intention is to only do with HTML and CSS

  • Got it, the effect of going up and down is possible to do, but the click event is only possible with javascript

  • Hugo my question has nothing to do with your :) Guy like I do to make these animations?

  • 1

    @Leandrade this particular example of the component I took from Quasar you can see here, just click on qq button: http://v0-13.quasar-framework.org/components/toast.html now to record the screen that was what I did using a simple program called Screentogif. I simply put to record this piece of screen and it saves as an animated gif https://www.screentogif.com/? l=pt_br

  • Jóia man, it was a program just like it needed. Thanks Hugo!

  • 1

    @Leandrade this program is very light! Less than 3mb :D has helped me a lot and works super well. I just miss being able to draw on the screen, but I haven’t looked into it yet...

Show 2 more comments

2 answers

6


You can do something very close using an element that can receive user focus in conjunction with the selector :focus-within CSS. With this selector, you can change the position of the Toast when your button has the focus.

.toast > .btn {
    background-color: purple;
    border-radius: .5em;
    box-shadow: 0 .25em .5em 0 rgba(0, 0, 0, .25);
    padding: 1em;
    color: #fff;
    text-transform: uppercase;
    font-family: sans-serif;
    font-weight: bold;
    border: none;
    cursor: pointer;
    transition: background-color 250ms;
}
.toast > .btn:hover {
    background-color: rgb(100, 0, 100);
}

.toast > .toast-message {
    position: fixed;
    display: flex;
    bottom: -83px;
    left: 0;
    width: 100%;
    justify-content: space-between;
    background-color: rgb(100, 0, 100);
    font-family: sans-serif;
    transition: bottom .5s ease-out;
}
.toast > .toast-message {
    color: #fff;
    margin: 0;
    padding: 2em;
    text-decoration: none;
}

.toast:focus-within > .toast-message {
  bottom: 0;
}
<div class="toast">
  <button class="btn" for="open">TOAST</button>
  <p class="toast-message">Lorem, ipsum dolor.</p>
</div>

Note that instead of separating the action elements (button) and the message, both are within the same parent element (div.toast). Thus, when the element .toast has a child with the focus of the user - in this case the button -, the message .toast > .toast-message will be displayed by changing the position relative to the bottom edge of the screen.

The requirement that is not satisfied with this solution is to close the message just by pressing the X on the message, but in compensation, any click off the button will hide the message, as it will lose focus.

The same effect you get with .btn:focus + .toast-message { bottom: 0; }, replacing the use of :focus-within, as can be seen in https://jsfiddle.net/acwoss/rz9pswax/.

  • Very good! It is already an option, even with the detail of the focus

2

For those who want a version that only closes when clicking a button an option is using :target

inserir a descrição da imagem aqui

So you can make one link with a href calling the ID of Toast, and within the Toast there’s another link with a href empty, the intention of that href is to cause the Toast loss the :target, so it closes back to original position.

OBS: Keep in mind that the Toast closes when the :target is done in another element. So even having a close button, you can close it (whether or not) by clicking on some other link, because when the Toast loses the target in url it will close...

See the code for the image above:

.btn {
    background-color: purple;
    border-radius: .5em;
    box-shadow: 0 .25em .5em 0 rgba(0, 0, 0, .25);
    padding: 1em;
    color: #fff;
    text-transform: uppercase;
    font-family: sans-serif;
    font-weight: bold;
    border: none;
    cursor: pointer;
    transition: background-color 250ms;
}
.btn:hover {
    background-color: rgb(100, 0, 100);
}
.toast {
    position: fixed;
    display: flex;
    bottom: -100px;
    left: 0;
    width: 100%;
    justify-content: space-between;
    background-color: rgb(100, 0, 100);
    font-family: sans-serif;
    transition: bottom 500ms;
}
.toast:target {
    bottom: 0;
}
.toast p,
.toast a {
    color: #fff;
    margin: 0;
    padding: 2em;
    text-decoration: none;
}

    
<br>
<a class="btn" href="#toast">TOAST</a>
<br>
<div class="toast" id="toast">
    <p>
        Lorem, ipsum dolor.
    </p>
    <a href="#">
        X
    </a>
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.