¿Cómo hacer las esquinas redondas dentro de la caja y su borde?


Supongo que el título es un poco difícil de entender, así que te lo explicaré. Estoy tratando de lograr este efecto:

introduzca la descripción de la imagen aquí

(una caja que tiene esquinas redondeadas y su borde, que también tiene bordes redondeados).

He logrado hacer esto, usando la propiedad background-clip:

introduzca la descripción de la imagen aquí

(esquinas redondeadas para el borde pero no para la caja interior)

La pregunta es, ¿cómo puedo lograr esquinas redondeadas para la caja interior?

Gracias ¡tú!

EDITAR

El HTML que estoy usando:

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

Y el 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);
}
Author: gentil papillon, 2011-01-30

7 answers

Cálculos del borde interior

Primero, necesitarás eliminar -vendor-background-clip: padding-box o establecerlos en border-box el valor predeterminado para lograr el radio del borde interior.

El radio del borde interior se calcula como la diferencia entre el radio del borde exterior (border-radius) y el ancho del borde (border-width) de tal manera que

inner border radius = outer border radius - border width

Siempre que el border-width es mayor que el border-radius, el radio del borde interior es negativo y se obtienen algunas esquinas invertidas incómodas. Actualmente, no cree que hay una propiedad para ajustar el inner-border-radius, por lo que tendrá que calcularlo manualmente.

En su caso:

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

Su nuevo CSS debe ser:

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

Simplemente reste los valores border-radius (6px) del valor border-width (5px) para lograr su radio de borde interior deseado:


Código que funciona para mí

Probado en Firefox 3.x, Google Chrome y 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 */

Adición de superposiciones de color 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>

No estoy completamente seguro de cómo hacer aritmética hexadecimal en JavaScript, pero estoy seguro de que puedes encontrar un algoritmo en Google.


Aplicación de Fronteras generales

¿Está utilizando una casilla separada <div> para su frontera a través de su propiedad background? Si es así, deberá aplicar border-radius y sus propiedades específicas del proveedor tanto en el cuadro de borde como en el cuadro interno:

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

Una manera mucho más eficiente simplemente tendría el inner-box gestiona su propio borde:

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

En cuanto a CSS, podrías declarar una clase .rounded-border y aplicarla a cada caja que tenga bordes redondeados:

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

Y aplicar la clase a cualquier caja que tenga bordes redondeados:

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

Para un solo elemento box, todavía se le pedirá que declare el tamaño del borde para que se muestre:

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

<div id="inner-box" class="rounded-borders">
</div>
 34
Author: Gio Borje,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-30 18:53:45

Otra solución es tener bordes interiores y exteriores que coincidan combinados con border-radius es "falsificar" el borde usando el <spread-radius> valor de la propiedad box-shadow. Esto produce una sombra sólida que puede pasar fácilmente por un borde regular.

Por ejemplo, para lograr un borde de 4px y un radio de borde blanco de 4px, intente esto:

/* 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 desea agregar una sombra paralela "real" a todo el contenedor, simplemente puede encadenar sus declaraciones de sombra como entonces:

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

Nota: tenga en cuenta que el orden de las declaraciones es el orden en que van a ser prestados.

Lo único a tener en cuenta es que el "borde falso" inicial se superpondrá a los primeros X píxeles (donde X es el ancho del borde) de cualquier sombra que desee debajo de él (y combinar, si está utilizando la opacidad RGBa en él por debajo del 100%.)

Así que no funcionará en todas las situaciones, pero obtendrá la mayoría. Uso esto con bastante frecuencia cuando las fronteras regulares no son ideales.

 17
Author: nickb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-28 23:33:35

Dado que no hay tal cosa como inner-border-radius para CSS, los navegadores lo predeterminan a border-radius - border-width. Si no te gusta eso, la solución típica es crear dos divs con bordes para imitar el radio del borde interior, pero esta solución aporta más diseño al html. También es una molestia si se trata de una plantilla de borde común utilizada en todo el sitio.

Me las arreglé para encontrar una manera de mantenerlo todo en css produciendo el div interno usando :after y content: "". Así que para su caso sería:

.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;
}
 13
Author: Leo Wu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-11 11:03:50

Necesitas tener dos elementos div, uno dentro del otro, y usar un css de esquina redondeada del navegador cruzado, como este:

.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
Author: Shaun McCran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-30 18:55:25

El problema no es la codificación del CSS sino las matemáticas de un círculo. Esencialmente su border-inner-radius (sé que esta propiedad no existe) es igual a la border-radius - border-width.

Simplemente calcule cuál desea que sea su radio interior y luego agregue el ancho del borde para lograr el efecto deseado.

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

 2
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-19 01:10:18

Basado en la idea de Leo Wu, aquí está mi solución:

.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>
 1
Author: Zsolti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-26 20:19:16

Debe hacer que el radio del borde sea un valor mayor que el ancho del borde hasta que comience a ver una curva. No es una fórmula establecida para establecer el radio de borde de +1px mayor que border-width. Sin embargo, va a ser un valor positivo, definitivamente. Necesita experimentar en los diferentes navegadores donde necesita esto hasta que vea el valor de radio de borde más pequeño posible que funcione lo suficientemente bien para usted en la mayoría de los navegadores. (Es posible que algunos navegadores no admitan esto.) Por ejemplo, en Google Chrome, Establecí un ancho de borde a 10px, pero tuve que establecer el radio de borde a 13px antes de comenzar a ver una apariencia de una curva de borde interior, mientras que 15px funcionó aún mejor.

 0
Author: Volomike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-31 08:01:59