Skip to content Home - me2 Accessibility logo

Accessible flip card

Flip cards for mouse, keyboard, and screen reader users

Flip Card

A flip card is a panel that can be rotated to display additional content at the back of the panel. As such, a flip card is an alternative way of expanding content. The flipping of the card is typically triggered by:

  • Mouse hover and keyboard focus, or
  • Pressing a button on the visible side of the card.

For compliance to WCAG 2.2, the following four success criteria are especially relevant:

  • 2.1.1 Keyboard : the keyboard focus can be moved to the flip card and the flip action triggered via keyboard. The action can trigger directly on focus or when the Enter or Spacebar keys are pressed.
  • 4.1.2 Name, Role, Value : both sides of the flip card are accessible via screen reader and the flip action (if triggered by a button) is conveyed via text or markup.
  • 1.4.13 Content on Hover or Focus : for flip cards that flip on mouse hover or keyboard focus: pressing the Escape key flips the card back to the state it was in before the interaction.
  • 2.4.7 Focus Visible : links and buttons on the hidden side of the flip card cannot gain keyboard focus, or if they can, the focus triggers the flip action so the focused element becomes visible.

The implementations below are two examples of WCAG compliant flip cards.

Button trigger flip card

This flip card is implemented as typical expanding content: the trigger is a button with an 'aria-expanded' attribute and the expanding content (the back of the card) is placed in the DOM sequence immediately after the trigger. When the back is displayed, the value of 'aria-expanded' is "true" and when hidden the value is "false". The trigger buttons label is "flip card".

When the front of the card is showing, the back is not available via screen reader, as it is hidden via the CSS rule "display:none". However, when the back is showing, the hidden front remains available via screen reader, as it is hidden via a CSS rotation. Therefore, from a screen reader user's perspective, the only change in content is the expansion/collapse of the back.

Eastern rosella

Photo of bird with curved white beak, red head and chest, white area under the beak, a yellow and green body with areas of red, black, and blue on the wings and tail.

The eastern rosella (Platycercus eximius) is a parrot native and endemic to south-eastern Australia.

It was first introduced to New Zealand in cages, which then both intentionally released and accidentally escaped into the wild and has been found establishing mainly in the North Island (notably in the northern half of the island, Taranaki, Waikato and in the Hutt Valley) and in the hills around Dunedin in the South Island since the early 20th century.

Rainbow lorikeet

Photo of bird with curved red beak, blue head, light green neck, red and yellow chest, and a predominantly green body.

The rainbow lorikeet (Trichoglossus moluccanus) is a species of parrot found in Australia. It is common along the eastern seaboard, from northern Queensland to South Australia. Its habitat is rainforest, coastal bush and woodland areas. Six taxa traditionally listed as subspecies of the rainbow lorikeet are now treated as separate species (see Taxonomy).

Rainbow lorikeets have been introduced to Perth, Western Australia; Tasmania; Auckland, New Zealand; and Hong Kong.

Galah

Photo of bird with curved grey beak, light grey top of head, pale rose head, chest, and neck and a grey body.

The galah (Eolophus roseicapilla), is an Australian species of cockatoo and the only member of the genus Eolophus.

The galah is adapted to a wide variety of modified and unmodified habitats and is one of Australia's most abundant and widespread bird species. The species is endemic to mainland Australia. It was introduced to Tasmania, where it is now widespread, in the mid-20th century and much more recently to New Zealand.

In the DOM sequence, the button is placed above the back of the card; however, visually, the button is positioned below this content. This means the visual focus outline would move from the bottom of the card up to the top of the card (if there are links or buttons in the content) and this is not a logical direction.

To remedy this, the button itself does not show any visual change on keyboard focus and instead, the entire card shows the focus outline. This ensures the visual keyboard focus order is logical, as it moves from the card into the content of the card.

Markup and code example

HTML

<div class="flip-card">
    <div class="card">

        <div class="front">
            <h3>
                Eastern rosella
            </h3>
            <img src="tools/fc/eastern_rosella.jpg" alt="Photo of bird with curved white beak, red head and chest, white area under the beak, a yellow and green body with areas of red, black, and blue on the wings and tail.">
        </div>

        <button aria-label="flipcard" aria-expanded="false"></button>

        <div class="back">
            <p>The <b>eastern rosella</b> (<i> <b>Platycercus eximius</b></i>) is a
                <a href="https://en.wikipedia.org/wiki/Parrot">
                    parrot
                </a>
                native and endemic to south-eastern
                <a href="https://en.wikipedia.org/wiki/Australia">
                    Australia
                </a>
                .
            </p>
            <p>
                It was first introduced to
                <a href="https://en.wikipedia.org/wiki/New_Zealand">
                    New Zealand
                </a>
                in cages, which then both intentionally released and accidentally escaped into the wild and has been found establishing mainly in the North Island (notably in the northern half of the island, Taranaki, Waikato and in the Hutt Valley) and in the hills around Dunedin in the South Island since the early 20th century.
            </p>
        </div>

    </div>
</div>

CSS

.cards.click .flip-card {
    background-color: transparent;
    width: 269px;
    height: 435px;
    border: 0;

    .card {
        position: relative;
        width: 100%;
        height: 100%;
        border-radius: 19px;
        outline-offset: 2px;
        transition-duration: 0.9s;
        transform-style: preserve-3d;
        perspective: 999px;

        /*Outline on .card animates in Chrome, so instead place outline on .front and .back*/
        &:has(button:focus-visible) {
            .front, .back{
                outline: 2px solid #096D96;
            }
        }

        .front, .back {
            position: absolute;
            width: 100%;
            height: 100%;
            border-radius: 19px;
            outline-offset: 2px;
            overflow: hidden;
            -webkit-backface-visibility: hidden;
            backface-visibility: hidden;
        }

        .back {
            transform: rotateY(-180deg);
            display: none;
        }

        button {
            position: absolute;
            left: 0;
            right: 0;
            bottom: 0;
            height: 41px;
            z-index: 99;
            border: 0;
            outline: 0;
            padding: 2px 5px;
            background-color: transparent;
            background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 97 89"><path style="stroke:rgb(9,109,150);stroke-width:14;fill:none" d="M0,82 L75,82 C85,82 90,77 90,67 L90,47 C90,37 85,27 75,27 h-35"/><path style="fill:rgb(9,109,150)" d="M15,27 L53,0 53,55 Z"/></svg>');
            background-size: 21px;
            background-repeat: no-repeat;
            background-position: center right 11px;

            &:hover {
                background-color: transparent;
                box-shadow: none;
                transform: none;
            }
        }

        /*General styling */
        .front, .back {
            padding: 11px;
            background-color: #F6FCFE;
            border: 2px solid #096D96;
            h3{
                width: fit-content;
                margin: 31px auto;
            }
            img {
                width: 100%;
            }
        }
    }

    &.moving {
        pointer-events: none;
        .card .back {
            display: block;
        }
    }

    &:has(button[aria-expanded="true"]) {
        .card {
            transform: rotateY(-180deg);
            /*Ensure the back remains visible after "moving" class is removed*/
            .back{
                display: block;
            }
        }
    }
}

JavaScript

{
    const flipCardClick = document.querySelectorAll("div.cards.click .flip-card");

    for(const flipCard of flipCardClick){

        const Back =  flipCard.querySelector(".back");
        const Btt = flipCard.querySelector("button");

        flipCard.addEventListener("click",(ev)=>{
            //If .back does not contain links or buttons, this check can be removed
            if(Back.contains(ev.target)){return}

            flipCard.classList.add("moving");

            if(Btt.getAttribute("aria-expanded") === "false"){
                Btt.setAttribute("aria-expanded","true");
            }else{
                Btt.setAttribute("aria-expanded","false");
            }
        });

        flipCard.addEventListener("transitionend",()=>{

            //If focus is moved to .back after button is pressed, move it back to the button
            if(Btt.getAttribute("aria-expanded") === "false" && Back.contains(document.activeElement)){
                Btt.focus();
            }
            flipCard.classList.remove("moving");
        });
    }
}

Hover and focus trigger flip card

In this flip card, the front and the back are available via keyboard and screen reader, regardless of the state of the card. Therefore, there is no functionality from a screen reader perspective, only static content, as the screen reader will read the front of the card first, followed by the back of the card.

To provide keyboard access to the card, the card shows the back when it gains keyboard focus. This also ensures the keyboard focus is visible (i.e. when sighted keyboard-only users press the Tab key to move focus through the content, the link or button that has focus will be visible).

Users of screen magnification software typically move the zoomed viewport via the mouse cursor (i.e. the user can only see content that is close to the cursor); however, hovering the cursor over a card flips it, so the user cannot see the front. To remedy this, users can press the Escape key to flip the card again and reveal the front, without having to move the cursor away.

Superb fairywren

Photo of two birds with straight beaks, one has a dark blue beak, aqua and dark blue head, neck, and chest, with a grey body, the other has a white chest, a predominantly grey body, a light orange beak, and light orange markings around the eyes.

The superb fairywren (Malurus cyaneus) is a passerine bird in the Australasian wren family, Maluridae, and is common and familiar across south-eastern Australia.

It is a sedentary and territorial species, also exhibiting a high degree of sexual dimorphism; the male in breeding plumage has a striking bright blue forehead, ear coverts, mantle, and tail, with a black mask and black or dark blue throat.

Crimson rosella

Photo of bird with curved grey beak, predominantly red body with blue on the wings, tail, and area under the beak.

The crimson rosella (Platycercus elegans) is a parrot native to eastern and south eastern Australia which has been introduced to New Zealand and Norfolk Island. It is commonly found in, but not restricted to, mountain forests and gardens.

The species as it now stands has subsumed two former separate species, the yellow rosella and the Adelaide rosella. Molecular studies show one of the three red-coloured races, P. e. nigrescens, is genetically more distinct.

Sulphur-crested cockatoo

Photo of bird with dark grey curved beak, white head with a yellow crest and a white body.

The sulphur-crested cockatoo (Cacatua galerita) is a relatively large white cockatoo found in wooded habitats in Australia, New Guinea, and some of the islands of Indonesia. They can be locally very numerous, leading to them sometimes being considered pests.

A highly intelligent bird, they are well known in aviculture, although they can be demanding pets.

Markup and code example

HTML

<div class="flip-card">
    <div class="card">

        <div class="front">
            <h3>
                Superb fairywren
            </h3>
            <img src="superb_fairywren.jpg" alt="Photo of two birds with straight beaks, one has a dark blue beak, aqua and dark blue head, neck, and chest, with a grey body, the other has a white chest, a predominantly grey body, a light orange beak, and light orange markings around the eyes.">
        </div>

        <!-- add tabindex="0" if the back does not contain links or buttons -->
        <div class="back">
            <p>
                The <b>superb fairywren</b> (<i><b>Malurus cyaneus</b> </i>) is a
                <a href="/wiki/Passerine">
                    passerine
                </a>
                <a href="/wiki/Bird">
                    bird
                </a>
                in the
                <a href="/wiki/Australasian_wren">
                    Australasian wren
                </a>
                family, Maluridae, and is common and familiar across south-eastern Australia.
            </p>
            <p>
                It is a sedentary and territorial species, also exhibiting a high degree of sexual dimorphism; the male in breeding plumage has a striking bright blue forehead, ear coverts, mantle, and tail, with a black mask and black or dark blue throat.
            </p>
        </div>

    </div>
</div>

CSS

.cards.hover .flip-card {
    background-color: transparent;
    width: 269px;
    height: 435px;
    border: 0;

    .card {
        position: relative;
        width: 100%;
        height: 100%;
        border-radius: 19px;
        outline-offset: 2px;
        transition-duration: 1.1s;
        transform-style: preserve-3d;
        perspective: 999px;

        .front, .back {
            position: absolute;
            width: 100%;
            height: 100%;
            border-radius: 19px;
            overflow: hidden;
        }

        .back {
            outline-offset: 2px;
            transform: rotateY(-180deg);
            -webkit-backface-visibility: hidden;
            backface-visibility: hidden;
        }

        .front, .back {
            padding:11px;
            background-color: #F6FCFE;
            border:2px solid #096D96;
            h3{
                width:fit-content;
                margin:31px auto;
            }
            img {
                width:100%;
            }
        }
    }

    &:hover .card:not(.escape){
        transform:rotateY(-180deg);
    }
    .card:has(:focus-visible):not(.escape){
        transform:rotateY(-180deg);
    }
}

JavaScript

{
    document.body.addEventListener("keydown", (ev) => {
        if(ev.key !== "Escape"){return}

        const hoverCard = document.querySelector("div.cards.hover .flip-card:hover .card");
        const focusCard = document.querySelector("div.cards.hover .card:has(:focus-visible)");

        if(hoverCard){
            hoverCard.classList.add("escape");
            hoverCard.addEventListener("mouseleave",()=>{
                hoverCard.classList.remove("escape");
            },{once:true});
        }

        if(focusCard){
            focusCard.classList.add("escape");
            focusCard.addEventListener("blur",()=>{
                focusCard.classList.remove("escape");
            },true,{once:true});
        }
    });
}

Terms of Use

This software is being provided "as is" - without any express or implied warranty. In particular, me2 Accessibility does not make any representation or warranty of any kind concerning the reliability, quality, or merchantability of this software or its fitness for any particular purpose. In addition, me2 Accessibility does not guarantee that use of this tool will ensure the accessibility of your web content or that your web content will comply with any specific accessibility standard.

Creative commons licence - logo
This work is licensed under a Creative Commons License

Contact Us

Need a quote / Have a query?

Please get in touch

Contact Us
Level AA conformance, W3C WAI Web Content Accessibility Guidelines 2.2 Certified WCAG level AA. me2Accessibility logo