web-dev-qa-db-de.com

Wie werden runde Ecken sowohl innerhalb einer Box als auch an der Grenze gemacht?

Ich denke, der Titel ist schwer zu verstehen, also erkläre ich ... Ich versuche diesen Effekt zu erreichen:

enter image description here

(eine Box mit abgerundeten Ecken und deren Rand, die ebenfalls abgerundete Ränder hat).

Dies ist mir mit der background-clip-Eigenschaft gelungen:

enter image description here

(abgerundete Ecken für Rand aber nicht für Innenbox)

Die Frage ist, wie kann ich für die Innenbox abgerundete Ecken erzielen?

Vielen Dank!

EDIT

Das HTML, das ich verwende:

<header class="body template-bg template-border radius-all">
        <nav>
            <ul>
                <li><a href="#">Link 1</a></li>
                <li><a href="#">Link 2</a></li>
                <li><a href="#">Link 3</a></li>
                <li><a href="#">Link 4</a></li>
            </ul>
        </nav>
    </header>

Und das CSS:

.radius-all {
  border-radius: 10px;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
}

.template-bg {
  background: #FFF;
  -moz-background-clip: padding;
  -webkit-background-clip: padding;
  background-clip: padding-box;
}

.template-border {
  border: 5px solid rgba(255, 255, 255, 0.2);
}
39
linkyndy

Berechnungen der inneren Grenze

Zuerst müssen Sie -vendor-background-clip: padding-box entfernen oder sie auf border-box setzen, um den inneren Randradius zu erreichen.

Der innere Randradius wird als Differenz des äußeren Randradius (border-radius) und der Randbreite (border-width) berechnet 

inner border radius = outer border radius - border width

Wenn der border-width größer ist als der border-radius, ist der innere Randradius negativ und Sie erhalten unangenehme umgekehrte Ecken. Derzeit glaube ich nicht, dass es eine Eigenschaft gibt, um den inner-border-radius anzupassen. Sie müssen ihn daher manuell berechnen.

In Ihrem Fall:

inner border radius = 6px - 5px = 1px

Ihr neues CSS sollte sein:

.radius-all { border-radius: 6px; -moz-border-radius: 6px; -webkit-border-radius: 6px; }
.template-bg { background: #FFF; }
.template-border { border: 5px solid rgba(255, 255, 255, 0.2); }

Subtrahieren Sie einfach die border-radius (6px) -Werte vom border-width-Wert (5px), um den gewünschten Innenradius zu erhalten: 


Code, der für mich funktioniert

Getestet mit Firefox 3.x, Google Chrome und Safari 5.0

 .radius-all { border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; }
.template-bg { background: #FFF; }
.template-border { border: 5px solid rgba(0, 0, 0, 0.2); } /* Note that white on white does not distinguish a border */

Hinzufügen von Farbüberlagerungen in JavaScript

<script type="text/javascript">
    var bodyBgColor = document.getElementsByTagName('body')[0].style.backgroundColor;;

    // insert opacity decreasing code here for hexadecimal

    var header = document.getElementsByTagName('header')[0];
    header.style.backgroundColor = bodyBgColor;
</script>

Ich bin nicht ganz sicher, wie man hexadezimale Arithmetik in JavaScript ausführt, aber ich bin mir sicher, dass Sie einen Algorithmus in Google finden können.


Allgemeine Grenzen anwenden

Verwenden Sie eine separate Box <div> für Ihre Grenze durch ihre background-Eigenschaft? In diesem Fall müssen Sie border-radius und seine herstellerspezifischen Eigenschaften sowohl für das Rahmenfeld als auch für das Innenfeld anwenden:

<div id="border-box" style="border-radius: 5px;">
    <div id="inner-box" style="border-radius: 5px;">
    </div>
</div>

Ein wesentlich effizienterer Weg würde die Innenbox einfach über eine eigene Grenze verfügen:

<div id="inner-box" style="border: 4px solid blue; border-radius: 5px">
    <!-- Content -->
</div>

In CSS könnten Sie einfach eine .rounded-border-Klasse deklarieren und auf jede Box mit abgerundeten Rahmen anwenden:

.rounded-borders {
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    -khtml-border-radius: 5px;
}

Wenden Sie die Klasse auf alle Boxen an, die abgerundete Rahmen haben:

<div id="border-box" class="rounded-borders">
    <div id="inner-box" class="rounded-borders">
    </div>
</div>

Für ein einzelnes Boxelement müssen Sie dennoch die Rahmengröße angeben, um angezeigt zu werden:

<style type="text/css">
    #inner-box { border: 4px solid blue; }
</style>

<div id="inner-box" class="rounded-borders">
</div>
35
Gio Borje

Eine andere Lösung besteht darin, dass innere und äußere Ränder mit border-radius zusammenpassen, indem der Rand mithilfe des <spread-radius> -Werts der box-shadow-Eigenschaft "gefälscht" wird. Dadurch wird ein solider Schatten erzeugt, der für eine reguläre Grenze leicht passieren kann.

Um beispielsweise einen 4px-Rand und einen 4px-weißen Randradius zu erzielen, versuchen Sie Folgendes:

/* rounded corners */
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;

/* drop shadow */
-webkit-box-shadow: 0px 0px 0px 4px #fff;
-moz-box-shadow: 0px 0px 0px 4px #fff;
box-shadow: 0px 0px 0px 4px #fff;

Wenn Sie dem gesamten Container einen "echten" Schlagschatten hinzufügen möchten, können Sie Ihre Schattenanweisungen einfach wie folgt verketten:

/* drop shadow */
-webkit-box-shadow: 0px 0px 0px 4px rgba(255,255,255,1.0),
        1px 1px 8px 0 rgba(0,0,0,0.4);
-moz-box-shadow: 0px 0px 0px 4px rgba(255,255,255,1.0),
        1px 1px 8px 0 rgba(0,0,0,0.4);
box-shadow: 0px 0px 0px 4px rgba(255,255,255,1.0),
        1px 1px 8px 0 rgba(0,0,0,0.4);

Anmerkung: Beachten Sie hierbei, dass die Reihenfolge der Anweisungen die Reihenfolge ist, in der sie gerendert werden.

Es ist nur zu beachten, dass der anfängliche "Faux-Rand" die ersten X-Pixel (wobei X die Breite des Randes darstellt) eines beliebigen darunter liegenden Schattens überlappt (und kombiniert, wenn Sie RGBa-Deckkraft verwenden.) unter 100%.)

In all-Situationen wird es nicht funktionieren, aber es wird die Mehrheit bekommen. Ich benutze das ziemlich häufig, wenn reguläre Grenzen nicht ideal sind.

18
nickb

Da es für CSS kein inner-border-radius gibt, wird es von den Browsern standardmäßig auf border-radius - border-width gesetzt. Wenn Sie das nicht mögen, besteht die typische Lösung darin, zwei divs mit Rändern zu erstellen, um den inneren Randradius zu imitieren. Diese Lösung bringt jedoch mehr Design in die HTML-Datei. Es ist auch ein Schmerz, wenn es sich um eine übliche Rahmenvorlage handelt, die in der gesamten Site verwendet wird. 

Ich konnte einen Weg finden, alles in css zu behalten, indem ich das innere div mit :after und content: "" erstellte. Für Ihren Fall wäre es also:

.template-border {
    position: relative;
    border-radius: 5px;
    background-color: #000;
    border: 10px solid #000;
    z-index: -2;
}

.template-border:after {
    content: "";
    display: block;
    position: absolute;
    width: 100%;
    height: 100%;
    border-radius: 5px;
    background-color: #FFF;
    z-index: -1;
}
14
Leo Wu

Basierend auf der Idee von Leo Wu ist dies meine Lösung:

.my-div
{
  background-color: white;
  border: solid 20px black;
  border-radius: 10px;
  box-shadow: 0 0 10px black;
  height: 100px;
  left: 30px;
  position: relative;
  top: 20px;
  width: 200px;
}
.my-div:before
{
  background-color: white;
  border-radius: 5px;
  content: "";
  display: block;
  height: calc(100% + 20px);
  left: -10px;
  position: absolute;
  top: -10px;
  width: calc(100% + 20px);
  z-index: 1;
}
.some-content
{
  height: calc(100% + 20px);
  left: -10px;
  position: relative;
  top: -10px;
  width: calc(100% + 20px);
  z-index: 3;
}
.some-header
{
  background-color: green;
  border-radius: 5px 5px 0 0;
  height: 30px;
}
<html>
	<body>
		<div class="my-div">
			<div class="some-content">
				<div class="some-header">my title</div>
				<div>some other content</div>
			</div>
		</div>
	</body>
</html>

3
Zsolti

Sie müssen zwei div-Elemente ineinander haben und eine css mit abgerundeten Ecken eines Cross-Browsers verwenden:

.small-rounded {
    border: 1px solid ##000;
    -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px;
    -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px;
    -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px;
    -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px;
    border-radius: 5px;
}
2
Shaun McCran

Das Problem ist nicht die Codierung des CSS, sondern die Mathematik eines Kreises. Im Wesentlichen ist Ihr border-inner-radius (ich weiß, dass diese Eigenschaft nicht existiert) gleich dem border-radius - border-width.

Ermitteln Sie einfach den gewünschten Innenradius und fügen Sie dann die Breite des Randes hinzu, um den gewünschten Effekt zu erzielen.

border-inner-radius + border-width = border-radius

2
Daniel

Sie müssen den Randradius auf einen Wert einstellen, der größer als die Randbreite ist, bis Sie eine Kurve sehen. Es ist keine festgelegte Formel, um den Randradius von + 1px größer als die Randbreite zu setzen. Es wird jedoch definitiv ein positiver Wert sein. Sie müssen an den verschiedenen Browsern dort experimentieren, wo Sie dies benötigen, bis Sie den kleinstmöglichen Grenzradiuswert sehen, der in den meisten Browsern für Sie gut genug ist. (Einige Browser unterstützen dies möglicherweise nicht.) Zum Beispiel habe ich in Google Chrome eine Randbreite auf 10px festgelegt, musste jedoch den Randradius auf 13px setzen, bevor ich einen Schein einer inneren Randkurve sah, während 15px noch besser gearbeitet.

0
Volomike

Nur für den Fall, dass jemand nach dieser Antwort googelt und hierher geschickt wird, ist hier der einfache Weg, dies zu tun ...

Beispiel HTML ...

<div class="wrapper">
    <div class="content">
        your content goes here
    </div>
</div>

Beispiel CSS ...

.wrapper {
    border-radius: 25px;
    border: solid 25px blue;
    background-color: blue;
}
.content {
    border-radius: 10px;
    background-color: white;
}

... Presto. enter image description here

0
Nick Steele