Héritage du border-radius

Petit topo sur certaines difficultés rencontrées dans l'affichage d'un élément et que son parent possède une courbure de bordure. L'héritage simple n'est pas toujours suffisant.

Le problème est que parfois le contenu peut déborder à l'extérieur du parent si la courbure est trop importante comme dans l'exemple ci-cessous :

<div class="parent">
    <div class="child"></div>
</div>
Élément avec un simple enfant.
.parent {
    width: 100%;
    border: 10px solid red;
    border-radius: 60px;
    background: white;
}
.child {
    width: 100%;
    height: 120px;
    background-color: green;
}
Styles appliqués au parent et à l'enfant.
Rendu.

Le moyen le plus simple de corriger cela est de masquer tout ce qui déborde du parent avec un overflow: hidden. Lorsque l'on ne peut pas utiliser cette technique, il est possible de faire hériter l'enfant de la courbure du parent avec un border-radius: inherit ; sauf que la solution est imparfaite dans certains cas, selon les dimensions de l'enfant ou quand le parent à une bordure et l'enfant non par exemple :

Héritage du border-radius par l'enfant.

Pour gérer ces cas là, il faut en passer par un calcul dynamique de la courbure de l'enfant. En voici un exemple parmi d'autre :

const BORDER_SIDES = ['Top', 'Bottom'];

const RADIUS_SIDES = ['Left', 'Right'];

/**
 * Calcul de la courbure de bordure d'un enfant en fonction
 * de celle du parent.
 * @param {HTMLElement} parent Parent portant la courbure
 * @param {HTMLElement} child Enfant sur lequel transférer 
 * la courbure.
 */
window.inheritRadius = function (parent, child) {
    let style = window.getComputedStyle(parent, null);
    if (style) {
        BORDER_SIDES.forEach(function (side) {
            let size = style[`border${side}Width`];
            if (size) {
                size = parseInt(size, 10);
                RADIUS_SIDES.forEach(function (rside) {
                    var prop = `border${side}${rside}Radius`,
                        radius = style[prop],
                        delta = 0;
                    if (radius) {
                        radius = parseInt(radius, 10);
                        delta = radius - size;
                        if (delta < 0) {
                            delta = 0;
                        }
                        child.style[prop] = `${delta}px`;
                    }
                });
            }
        });
    }
};
Calcul dynamique de la courbure de bordure.
Calcul du border-radius de l'enfant'.