Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

The concentric border-radius rule: why nested rounded corners look slightly wrong

You round a card at 16px. You round the thumbnail inside it at 16px too, because that's the design token. Then you squint at it and something is off — the gap between the two curves looks fatter at the diagonal than it does along the s…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

You round a card at 16px. You round the thumbnail inside it at 16px too, because that's the design token. Then you squint at it and something is off — the gap between the two curves looks fatter at the diagonal than it does along the straight edges, and the inner corner reads as slightly pinched.



Your eyes are right. Two rounded rectangles only look parallel when their radii differ by exactly the distance between them.






The rule






inner radius = outer radius − gap






Where gap is the distance from the outer box's border edge to the inner box's border edge: border-width + padding.



The reason is just where the arc centres land. Put the outer box's top-left corner at (0, 0) with radius R: its corner arc is a quarter circle centred at (R, R). Inset the child by p on both sides and give it radius r, and its arc is centred at (p + r, p + r).



Those two centres coincide only when p + r = R, i.e. r = R − p. Concentric arcs, constant p gap the whole way round the curve. Any other value and the gap swells or collapses at 45°.






In CSS



Derive it instead of hardcoding two numbers that will drift apart the first time someone changes the padding:




.card {
--radius: 16px;
--pad: 8px;

padding: var(--pad);
border-radius: var(--radius);
}

.card > img {
border-radius: calc(var(--radius) - var(--pad)); /* 8px */
display: block;
width: 100%;
}









Clamp it, and mind the unit on the zero



When the padding exceeds the radius, calc() produces a negative length. Negative border-radius is invalid, so the whole declaration is thrown away and you inherit whatever was there before — usually not what you wanted, and silent. Clamp it:




border-radius: max(0px, calc(var(--radius) - var(--pad)));






Note it's 0px, not 0. Inside a CSS math function you can't compare a unitless number against a length; max(0, calc(...)) is invalid and gets dropped exactly like the negative value you were trying to avoid.






Borders count as gap



border-radius applies to the border box, and the browser already narrows the curve of a border's inner edge by the border width for you. But your child element sits border-width + padding in from the parent's border box, so both go into the subtraction:




.card {
--radius: 16px;
--border: 1px;
--pad: 12px;

border: var(--border) solid #d4d4d8;
padding: var(--pad);
border-radius: var(--radius);
}

.card > .inner {
border-radius: max(0px, calc(var(--radius) - var(--border) - var(--pad)));
}






Forgetting the border width is why 1px-off corners survive review — at 1px it's subtle, at 3px on a chunky outlined card it's obvious.






Uneven padding needs an ellipse



Horizontal padding is often bigger than vertical. One radius value can't stay parallel on both axes when the gaps differ, so give the corner two: a horizontal radius and a vertical one. The shorthand takes them either side of a slash.




.card {
--radius: 20px;
--pad-x: 12px;
--pad-y: 6px;

padding: var(--pad-y) var(--pad-x);
border-radius: var(--radius);
}

.card > .inner {
/* horizontal / vertical */
border-radius:
max(0px, calc(var(--radius) - var(--pad-x)))
/
max(0px, calc(var(--radius) - var(--pad-y)));
}






Strictly, the true parallel curve of a circle is another circle, not an ellipse — but this keeps both arc centres on the same point, and that's what reads as correct. It's how most design systems handle it.






The one that quietly breaks the math



The spec has an overlap rule: if the two radii on any one side add up to more than that side's length, the browser computes a scale factor f = min(side length ÷ sum of that side's two radii) across all four sides, and if f < 1 it multiplies every corner radius by f.



So border-radius: 40px on a chip that's 60px tall doesn't render at 40px. Each vertical side needs 40 + 40 = 80px of radius in a 60px space, so f = 0.75 and every corner comes out at 30px.



Your inner element never hears about this. It's still computing calc(40px - 12px) = 28px from the specified value, while the parent is actually drawing 30px. The gap is now wrong on every corner, and the DevTools computed style shows 40px, because the scaling happens at used-value time.



Two ways out:




  • Keep every radius at or below half the shortest dimension of the box, so f is always 1 and your arithmetic holds.

  • If you actually want a pill, don't derive anything — set a large radius on both boxes and let the rule do its job:




.pill        { border-radius: 999px; }
.pill > .dot { border-radius: 999px; }






Both get clamped to their own half-height, which is exactly the concentric result you'd have calculated by hand.






Checklist





  • inner = outer − (border-width + padding), derived with calc(), never two hardcoded tokens

  • Clamp with max(0px, …) — unit on the zero, or the declaration is invalid

  • Different horizontal and vertical gaps → use the horizontal / vertical slash form

  • Keep radii ≤ half the shortest side, otherwise the browser rescales all four and your derived value silently drifts

  • Pills are the exception: set both to a big number instead of subtracting



Once the arc centres line up, nested cards stop looking subtly cheap and you stop nudging values by 1px hoping it'll click.



I keep a small free border radius generator around for when I want to eyeball per-corner and elliptical values before committing them to tokens.

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Vulnerability Remediation & Verification
Syntax validiert (0 Fehler)
title: Detect Exploitation - The concentric border-radius rule: why nested rounded corners look slightly wrong
id: 65cafac5-fb75-4db2-ae9d-c73bd933f004
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-26
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-26"
        description = "YARA Signature for "
    strings:
        $str = "The concentric border-radius r" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("The concentric border-radius rule why ne")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*The concentric border-radius rule why ne*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "The concentric border-radius rule why ne"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich The concentric border-radius rule: why n.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-88003 | InvoicePlane is a self-hosted open source application for managing invoi…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag