DEV Community

artydev
artydev

Posted on

FastHTML : dealing with Modals with the help of Hyperscript

Here is a nice way to open a modal in FastHTML and Hyperscript
There is absolutely no Javascript

from fasthtml.common import *

app, rt = fast_app(
    hdrs=(
        StyleX("./static/styledev.css"),
        Script(src="https://unpkg.com/hyperscript.org@0.9.12"),
    ),
    live=True,
)


@app.get("/modal")
def modal():
    return Div(
        Div(_="on click trigger closeModal", cls="modal-underlay"),
        Div(
            H1("Modal Dialog"),
            P("This is the modal content"),
            P("You can put anything here, like text, or a form, or an image."),
            Button("Close", _="on click trigger closeModal", cls="btn danger"),
            cls="modal-content",
        ),
        id="modal",
        _="on closeModal add .closing then wait for animationend then remove me",
    )


@app.get("/")
def home():
    return Div(
        H2("Modal with FastHTML and Hyperscript", style="text-align:center"),
        Button(
            "Open a Modal",
            hx_get="/modal",
            hx_target="body",
            hx_swap="beforeend",
            cls="btn primary",
        ),
    )

serve(port=3333) 

Enter fullscreen mode Exit fullscreen mode

The CSS part :

/***** MODAL DIALOG ****/
#modal {
    /* Underlay covers entire screen. */
    position: fixed;
    top:0px;
    bottom: 0px;
    left:0px;
    right:0px;
    background-color:rgba(0,0,0,0.5);
    z-index:1000;

    /* Flexbox centers the .modal-content vertically and horizontally */
    display:flex;
    flex-direction:column;
    align-items:center;

    /* Animate when opening */
    animation-name: fadeIn;
    animation-duration:150ms;
    animation-timing-function: ease;
}

#modal > .modal-underlay {
    /* underlay takes up the entire viewport. This is only
    required if you want to click to dismiss the popup */
    position: absolute;
    z-index: -1;
    top:0px;
    bottom:0px;
    left: 0px;
    right: 0px;
}

#modal > .modal-content {
    /* Position visible dialog near the top of the window */
    margin-top:10vh;

    /* Sizing for visible dialog */
    width:80%;
    max-width:600px;

    /* Display properties for visible dialog*/
    border:solid 1px #999;
    border-radius:8px;
    box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.3);
    background-color:white;
    padding:20px;

    /* Animate when opening */
    animation-name:zoomIn;
    animation-duration:150ms;
    animation-timing-function: ease;
}

#modal.closing {
    /* Animate when closing */
    animation-name: fadeOut;
    animation-duration:150ms;
    animation-timing-function: ease;
}

#modal.closing > .modal-content {
    /* Animate when closing */
    animation-name: zoomOut;
    animation-duration:150ms;
    animation-timing-function: ease;
}

@keyframes fadeIn {
    0% {opacity: 0;}
    100% {opacity: 1;}
}

@keyframes fadeOut {
    0% {opacity: 1;}
    100% {opacity: 0;}
}

@keyframes zoomIn {
    0% {transform: scale(0.9);}
    100% {transform: scale(1);}
}

@keyframes zoomOut {
    0% {transform: scale(1);}
    100% {transform: scale(0.9);}
}

Enter fullscreen mode Exit fullscreen mode

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay