link - html title attribute
Efecto de borde degradado extraño (8)
Al aplicar un borde transparente sobre un elemento con un
linear-gradient
como fondo, obtengo un efecto extraño.
Observe que los lados izquierdo y derecho del elemento no tienen los colores adecuados (están cambiados de alguna manera) y son extrañamente planos .
HTML
<div class="colors">
</div>
CSS
.colors {
width: 100px;
border: 10px solid rgba(0,0,0,0.2);
height: 50px;
background: linear-gradient(to right,
#78C5D6,
#459BA8,
#79C267,
#C5D647,
#F5D63D,
#F08B33,
#E868A2,
#BE61A5);
}
¿Por qué esto muestra un efecto extraño en el lado izquierdo y derecho del elemento, y qué puedo hacer al respecto?
Aquí está el violín: http://jsfiddle.net/fzndodgx/3/
Solución
La forma más sencilla de solucionar este problema sería establecer el valor de la propiedad de
background-origin
como
border-box
.
.colors {
width: 100px;
border: 10px solid rgba(0, 0, 0, 0.2);
height: 50px;
background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
background-origin: border-box;
}
<div class="colors"></div>
Motivo del comportamiento mencionado en cuestión
Las siguientes son las propiedades de
background
relevantes que determinan la forma en que se muestra el gradiente de fondo para este caso:
-
background-origin
: el valor predeterminado espadding-box
. Significa que el fondo está realmente posicionado con respecto al cuadro de relleno y, por lo tanto, comienza después delborder
. -
background-repeat
- El valor predeterminado para esto esrepeat
. Significa que la imagen debe repetirse tanto como sea necesario para cubrir toda el área de pintura de fondo. -
background-clip
: el valor predeterminado para esto esborder-box
. Significa que la imagen también debe estar presente debajo del área ocupada por los bordes del cuadro.
Ahora, combinando los tres, podemos ver que el borde debe repetirse tanto como sea posible para que esté presente incluso debajo de los bordes y que su posición de inicio sea posterior al borde del cuadro. Esto implica que el fondo debe repetirse de manera cíclica para llenar el área debajo del borde en el lado izquierdo. Debido a esto, el borde izquierdo tiene el color como el extremo derecho del gradiente y viceversa.
Al cambiarlo a
border-box
, estamos haciendo que el fondo se posicione con respecto al cuadro de borde.
Esta configuración
también tiene un efecto sobre el tamaño de la imagen de fondo
y la razón por la que se describe a continuación en detalle.
¿Por qué
box-sizing: border-box
no funciona?
Establecer
box-sizing
border-box
como
border-box
no produce ningún cambio porque esa propiedad afecta solo el tamaño del cuadro.
No tiene absolutamente ningún efecto en lo siguiente:
- El tamaño de la imagen de degradado (la lógica de cálculo real se describe a continuación)
- El punto de partida (o posición) de la imagen de degradado
- La repetición de la imagen de fondo.
¿Cómo se calcula el tamaño del gradiente?
Según la
especificación W3C
, a continuación se muestra cómo se calculan las dimensiones de la imagen cuando no se proporciona un tamaño explícito (el valor predeterminado es
auto
).
Si la imagen no tiene un ancho intrínseco ni una altura intrínseca, su tamaño se determina como ''contener''
Tenga en cuenta cómo habla sobre el tamaño de la imagen y no el del cuadro.
En esencia, independientemente del tamaño del cuadro, el tamaño de la imagen de fondo se calcularía en función de la definición de la palabra clave que
contain
cuando la imagen en sí no tiene una altura intrínseca (
que los gradientes CSS no tienen imágenes diferentes
).
La
definición de
contain
es la siguiente:
Escale la imagen, conservando su relación de aspecto intrínseca (si existe), al tamaño más grande, de modo que tanto su ancho como su altura puedan caber dentro del área de posicionamiento del fondo .
El área de posicionamiento de fondo
se define de la siguiente manera (bajo la definición de propiedad de
background-origin
):
Para los elementos representados como un solo cuadro, especifica el área de posicionamiento de fondo
Por lo tanto, cuando la imagen no tiene una altura intrínseca (y en este caso tampoco tiene
background-size
), el tamaño de la imagen sería igual al valor del
background-origin
del
background-origin
(que en nuestro caso es
padding-box
).
Esta es la razón por la que incluso establecer el
box-sizing
del
box-sizing
como
border-box
no tiene efecto.
Nota: el énfasis dentro de los textos citados son todos míos
Si establece explícitamente el
background-size
del
background-size
como el tamaño del cuadro, notará cómo se resuelve el problema en el lado derecho pero no en el lado izquierdo.
Esto se debe a que ahora la imagen es lo suficientemente grande como para no repetirse debajo del borde derecho, pero su punto de partida sigue después del borde izquierdo.
.colors {
width: 100px;
border: 10px solid rgba(0, 0, 0, 0.2);
height: 50px;
background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
background-size: 110px 60px;
}
.colors-2 {
width: 100px;
border: 10px solid rgba(0, 0, 0, 0.2);
height: 50px;
background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
box-sizing: border-box;
background-size: 100px 50px;
}
<div class="colors">
</div>
<div class="colors-2">
</div>
El fondo se repite debajo del borde. El fondo se ejecuta solo en el "cuerpo" del elemento, debajo del borde hay una expansión y comienza a repetirse.
Vea
this
ejemplo
no-repeat
en el borde.
ACTUALIZAR
Jugar con la
position
y el
size
fondo puede ayudar expandiendo el fondo y luego ajustando su ubicación.
Mira este violín .
O ver fragmento:
.colors {
padding: 10px;
width: 100px;
border: 10px solid rgba(0, 0, 0, 0.2);
height: 50px;
background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
background-size: 117%;
background-position-x: 130px;
}
<div class="colors"></div>
El gradiente comienza dentro del cuadro de relleno de acuerdo con el comportamiento predeterminado del modelo de cuadro CSS, por lo que tiene sentido que los colores iniciales y finales aparezcan hasta el infinito a cada lado del gradiente, donde estaría el borde.
Lo mismo es cierto de este gradiente (NSFW):
Continúa infinitamente en el valor inicial (violeta) a la izquierda, y continúa infinitamente con el valor final (naranja) a la derecha. Puede continuar infinitamente hacia arriba con este gradiente, y así lo hace.
Esa es mi comprensión de por qué esto está apareciendo, una solución sería usar un modelo de caja diferente.
El valor predeterminado de la propiedad de
background-origin
de
background-origin
es
padding-box
que significa que el fondo está posicionado y dimensionado en relación con el cuadro de relleno.
El fondo también se
extiende
por debajo del borde, ya que la propiedad de
background-clip
defecto es
border-box
;
simplemente se repite debajo del borde.
Es por eso que ve el lado derecho del fondo debajo del borde izquierdo y viceversa.
Entonces, solo cambia el origen:
.colors {
width: 100px;
border: 10px solid rgba(0, 0, 0, 0.2);
height: 50px;
background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
background-origin: border-box;
}
<div class="colors"></div>
Alternativamente, puede jugar con el tamaño y la posición del fondo: agregue 20 píxeles al tamaño del fondo y colóquelo en -10 píxeles -10 píxeles:
.colors {
width: 100px;
border: 10px solid rgba(0, 0, 0, 0.2);
height: 50px;
background: linear-gradient(to right, #78C5D6, #459BA8, #79C267, #C5D647, #F5D63D, #F08B33, #E868A2, #BE61A5);
background-position: -10px -10px;
background-size: calc(100% + 20px) calc(100% + 20px);
}
<div class="colors"></div>
Está funcionando correctamente. Había usado un borde transparente en el bloque para ver bg-color. Su gradiente lineal por lo que su color sólido en el lado izquierdo y derecho. Si usa un borde sólido, puede ver el efecto adecuado. http://prntscr.com/7mo5jm
Esto se debe a que los puntos de inicio y finalización del
gradient
están en los bordes del
padding-box
y el
border
se representa fuera del
padding-box
.
Por lo tanto, los bordes se ven divertidos porque el
background
se repite en cada lado fuera del
padding-box
para cubrir el
border-box
.
El
box-shadow:inset
se representa dentro del
padding-box
(al igual que el fondo) y proporciona visualmente el mismo efecto que un
border
, por lo que puede intentar usarlo en lugar del
border
:
box-shadow: inset 0 0 0 10px rgba(0,0,0,0.2);
padding: 10px;
Debido a que una
box-shadow
no ocupa espacio, debe aumentar su relleno en consecuencia.
Ilustración de
padding-box
y
border-box
:
Otras respuestas ya han mostrado cómo solucionar el problema, pero pensé que debería señalar que si aumenta el
border-width
del
border-width
se hace evidente que el fondo se está repitiendo.
.colors {
width: 100px;
border: 100px solid rgba(0,0,0,0.2);
height: 50px;
background: linear-gradient(to right,
#78C5D6,
#459BA8,
#79C267,
#C5D647,
#F5D63D,
#F08B33,
#E868A2,
#BE61A5);
}
Producirá
Si no desea usar
box-shadow
, puede usar
border-image
y ajustar los colores del degradado:
http://jsfiddle.net/9pcuj8bw/5/
.colors {
width:100px;
height: 50px;
background: linear-gradient(to right,
#78C5D6,
#459BA8,
#79C267,
#C5D647,
#F5D63D,
#F08B33,
#E868A2,
#BE61A5) no-repeat;
border: 10px solid;
border-image: linear-gradient(to right,
#0bc3b8,
#068e8c,
#f8c617,
#ea5f24,
#b2492c) 1;
}
<div class="colors"></div>
Cuidado, esto no funciona en IE10 o inferior: http://caniuse.com/#feat=border-image