web-dev-qa-db-fra.com

Comment faire des coins arrondis à la fois à l'intérieur d'une boîte et de sa bordure?

Je suppose que le titre est un peu difficile à comprendre, je vais donc vous expliquer ... Je tente d’atteindre cet effet:

enter image description here

(une boîte qui a des coins arrondis et sa bordure qui a aussi des bords arrondis).

J'ai réussi à le faire en utilisant la propriété background-clip:

enter image description here

(coins arrondis pour la bordure mais pas pour la boîte intérieure)

La question est de savoir comment puis-je obtenir des angles arrondis pour la boîte intérieure?

Je vous remercie!

MODIFIER

Le HTML que j'utilise:

<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>

Et le 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

Calculs de frontière intérieure

Tout d'abord, vous devez supprimer -vendor-background-clip: padding-box ou les définir sur border-box par défaut afin d'obtenir le rayon de la bordure intérieure.

Le rayon de la bordure interne correspond à la différence entre le rayon de la bordure externe (border-radius) et la largeur de la bordure (border-width), de sorte que 

inner border radius = outer border radius - border width

Chaque fois que le border-width est supérieur au border-radius, le rayon de la bordure intérieure est négatif et vous obtenez des angles inversés gênants. Actuellement, je ne pense pas qu'il existe une propriété permettant d'ajuster le inner-border-radius; vous devez donc le calculer manuellement.

Dans ton cas:

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

Votre nouveau CSS devrait être:

.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); }

Soustrayez simplement les valeurs border-radius (6px) de la valeur border-width (5px) afin d’atteindre votre rayon intérieur souhaité: 


Code qui fonctionne pour moi

Testé sur Firefox 3.x, Google Chrome et 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 */

Ajout de superpositions de couleurs en 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>

Je ne suis pas tout à fait sûr de savoir comment faire de l'arithmétique hexadécimale en JavaScript, mais je suis sûr que vous pouvez trouver un algorithme dans Google.


Application des frontières générales

Utilisez-vous une zone distincte <div> pour votre bordure via sa propriété background? Si tel est le cas, vous devrez appliquer border-radius et ses propriétés propres au fournisseur, à la fois dans la zone de bordure et dans la zone intérieure:

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

Une solution beaucoup plus efficace consisterait simplement à ce que la boîte intérieure gère sa propre frontière:

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

En ce qui concerne CSS, vous pouvez simplement déclarer une classe .rounded-border et l’appliquer à chaque zone dont les bordures sont arrondies:

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

Et appliquez la classe à toutes les boîtes ayant des bordures arrondies:

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

Pour un élément de boîte unique, il vous sera toujours demandé de déclarer la taille de la bordure pour pouvoir être affichée:

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

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

Une autre solution consiste à combiner les bordures intérieure et extérieure correspondantes avec border-radius, c'est de "simuler" la bordure à l'aide de la valeur <spread-radius> de la propriété box-shadow. Cela produit une ombre solide qui peut facilement passer pour une bordure régulière.

Par exemple, pour obtenir une bordure de 4 pixels et un rayon de bordure blanche de 4 pixels, essayez ceci:

/* 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;

Si vous souhaitez ajouter une "vraie" ombre portée à l'ensemble du conteneur, vous pouvez simplement chaîner vos déclarations d'ombre comme suit:

/* 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);

Remarque: N'oubliez pas que l'ordre des instructions est celui dans lequel elles seront rendues.

La seule chose dont il faut se méfier, c’est que la "fausse bordure" initiale chevauche les X premiers pixels (où X est la largeur de la bordure) de toute ombre que vous voulez au-dessous (et se combine si vous utilisez l’opacité RGBa dessus). en dessous de 100%.)

Donc, cela ne fonctionnera pas dans les situations {toutes}, mais la majorité le sera. J'utilise cela assez souvent lorsque les frontières régulières ne sont pas idéales.

18
nickb

Comme inner-border-radius n'existe pas pour CSS, les navigateurs le configurent par défaut à border-radius - border-width. Si vous n'aimez pas cela, la solution typique est de créer deux div avec des bordures pour imiter le rayon de bord intérieur, mais cette solution introduit plus de design dans le code HTML. C'est également pénible s'il s'agit d'un modèle de bordure commun utilisé sur l'ensemble du site. 

J'ai réussi à trouver un moyen de tout garder en css en produisant la division interne en utilisant :after et content: "". Donc, pour votre cas, ce serait:

.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

Sur la base de l'idée de Leo Wu, voici ma solution:

.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

Vous devez avoir deux éléments div, l'un dans l'autre, et utiliser un css à coins arrondis dans le navigateur, comme ceci:

.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

Le problème n’est pas le codage de la CSS, mais la mathématique d’un cercle . Essentiellement, votre border-inner-radius (je sais que cette propriété n’existe pas) est égal à border-radius - border-width.

Déterminez simplement ce que vous voulez que votre rayon intérieur soit, puis ajoutez la largeur de la bordure pour obtenir l’effet souhaité.

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

2
Daniel

Vous devez définir le rayon de la bordure sur une valeur supérieure à celle de la largeur de la bordure jusqu'à ce que vous commenciez à voir une courbe. Ce n'est pas une formule définie pour définir un rayon de bordure supérieur de + 1px par rapport à la largeur de la bordure. Cependant, ce sera certainement une valeur positive. Vous devez faire des essais dans les différents navigateurs là où vous en avez besoin jusqu'à ce que vous voyiez la plus petite valeur possible de bord de rayon qui vous convient dans la plupart des navigateurs. (Certains navigateurs peuvent ne pas supporter cela.) Par exemple, dans Google Chrome, j’ai défini une largeur de bordure de 10 pixels, mais je devais définir un rayon de 13px avant de commencer à voir l’apparence d’une courbe travaillé encore mieux.

0
Volomike