Normal state:
Desired output in hover state:
I have a button that needs to clip the background on both the padding-box and the text in the hover state. I can achieve similiar behaviour by using border-image along with using background-clip: text, however there's no border-radius:
button {
background-color: #FFFFFF;
border: 2px solid black;
color: black;
padding: 15px 32px;
text-align: center;
border-radius: 5px;
}
button:hover {
border-image: url("https://i.imgur.com/drcgLxf.png");
border-image-slice: 30;
background: url("https://i.imgur.com/drcgLxf.png");
background-size: cover;
background-repeat: no-repeat;
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
<button>text here</button>
I found a way to use background-clip on both the text and the background itself by using a transparent border. I can't find a way to merge both of these together in a single hover state though, as there can only be specified a single background-clip on a single selector.
/* --- BACKGROUND CLIP TEXT ---*/
button.text {
border: 2px solid black;
border-radius: 5px;
background: white;
padding: 10px;
}
button.text:hover {
background: url("https://i.imgur.com/drcgLxf.png");
background-size: cover;
background-repeat: no-repeat;
z-index: 1;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* --- END ---*/
/* --- BACKGROUND CLIP PADDING-BOX ---*/
button.padding {
border: 2px solid black;
border-radius: 5px;
background: white;
background-clip: padding-box;
padding: 10px;
position: relative;
}
button.padding:hover {
border: 2px solid transparent;
}
button.padding::after {
position: absolute;
top: -2px;
bottom: -2px;
left: -2px;
right: -2px;
background: url('https://i.imgur.com/drcgLxf.png');
background-repeat: no-repeat;
background-size: cover;
content: '';
z-index: -1;
border-radius: 2px;
}
/* --- END --- */
<button class="text">clipped text</button>
<button class="padding">clipped padding-box</button>
Any JavaScript, jQuery or CSS-solution?
Use mask to combine both of them (related: Border Gradient with Border Radius)
button {
padding: 10px;
position: relative;
border: none;
background: var(--i,linear-gradient(#000 0 0)) center/cover repeat;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
button::after {
content: '';
position: absolute;
inset: 0;
padding: 2px; /* the border thickness */
border-radius: 5px;
background: inherit;
background-clip: padding-box;
-webkit-mask:
linear-gradient(#000 0 0) content-box,
linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
}
button:hover {
--i: url('https://i.imgur.com/drcgLxf.png');
}
<button class="text">clipped text</button>
Related
Is there a way to replicate YouTube's custom scrollbar?
Desired effect:
It seems like ::webkit-scrollbar-thumb has a left and right padding to achieve that effect.
I have tried the following:
* {
margin: 0;
padding: 0;
::-webkit-scrollbar {
background: #181818;
width: 12px;
}
::-webkit-scrollbar-thumb {
padding: 0 4px; // This was supposed to do the trick
background: #909090;
border-radius: 100px;
&:hover {
background: #606060;
}
}
}
But it doesn't work...
Result:
Any ideas how to achieve the desired effect? Thanks in advance.
You could try faking the padding with background-clip: padding-box and applying a transparent border-right and left.
::-webkit-scrollbar {
background: #181818;
width: 20px;
}
::-webkit-scrollbar-thumb {
padding: 0 4px;
border-right:4px solid transparent;
border-left:4px solid transparent;
background: #909090;
background-clip: padding-box;
border-radius: 100px;
&:hover {
background: #606060;
}
}
html,
body {
height: 300%;
}
I need to make a box with arrow for a tooltip but I can't use pseudo-elements because :
The box background is a little transparent
It has border
here is the example :
.box {
margin: 60px 0 0 0;
width: 250px;
height: 50px;
background-color: rgba(255, 144, 89, 0.5);
border-radius: 5px;
position: relative;
border: 2px solid #ff6e26;
}
.box:after,
.box:before {
bottom: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.box:after {
border-color: rgba(136, 183, 213, 0);
border-bottom-color: rgba(255, 144, 89, 0.5);
border-width: 10px;
margin-left: -10px;
}
.box:before {
border-color: rgba(194, 225, 245, 0);
border-bottom-color: #ff6e26;
border-width: 12px;
margin-left: -12px;
}
<div class="box"></div>
https://codepen.io/Masoudm/pen/qgvJGX
as you see when I make the background transparent it doesn't works for the arrow, because I already used ::before behind it for its border. I wonder if there is another approach which allows me to keep the box size dynamic.
Update:
the box should be something like this ( except the top curvy line)
Based on this previous answer I will adjust slightly the code to have a transparent background. There is two main tricks. Half the coloration of the pseudo element to avoid the intersection with the main element and the use of gradient on the main element to create the border top and create the hole for the pseudo element:
body {
margin:0;
background-image:linear-gradient(to right,yellow,pink);
}
.box {
border: 2px solid red;
border-top:transparent; /*make border-top transparent*/
margin: 50px;
height: 50px;
position:relative;
/* Use gradient to mimic the border top with a transparent gap */
background:
linear-gradient(red,red) left top /calc(50% - 10px*1.414) 2px,
linear-gradient(red,red) right top/calc(50% - 10px*1.414) 2px,
rgba(0,255,0,0.4);
background-repeat:no-repeat;
}
.box:before {
content: "";
position: absolute;
width: 20px;
height: 20px;
border-top: 2px solid red;
border-left: 2px solid red;
top: -11px;
left: calc(50% - 11px);
transform: rotate(45deg);
background:linear-gradient(-45deg,transparent 50%,rgba(0,255,0,0.4) 50%);
}
<div class="box">
</div>
* {
box-sizing: border-box;
font-family: inherit;
}
html {
font-size: 62.25%;
}
body {
padding: 50px;
}
.outter {
width: 200px;
height: 100px;
position: relative;
}
.box {
padding: 20px;
width: 100%;
height: 100%;
background: rgba(255, 68, 0, 0.568);
border: 3px solid orangered;
border-radius: 5px;
clip-path: polygon(0 0,45% 0,45% 10px,calc(45% + 15px) 10px,calc(45% + 15px) 0,100% 0,100% 100%,0 100%,0 0)
}
.arrow {
width: 15px;
height: 8px;
background: rgba(255, 68, 0, 0.568);
transform: translate(-67%, 100%);
position: absolute;
left: 50%;
bottom: 98%;
}
.arrow::after {
border: 3px solid transparent;
border-left-color: orangered;
border-top-color: orangered;
border-right: 0px solid transparent;
border-bottom: 0px solid transparent;
width: 11px;
height: 11px;
position: absolute;
left: 0;
bottom: 34%;
content: '';
transform: rotate(45deg);
background: linear-gradient(134deg,rgba(255, 68, 0, 0.56) 0%,rgba(255, 68, 0, 0.56) 50%,transparent 50%, transparent 100%);
}
<div class="outter">
<div class="arrow"></div>
<div class="box"></div>
</div>
I'm trying to create two half circles (each with a different color) which together form one circle. Something like this
DEMO
I created this using 2 elements and a bit of css:
<span class="circle-part half-left-circle"></span>
<span class="circle-part half-right-circle"></span>
and
$size: 100px;
$border: 20px;
...
.half-right-circle {
border-top-right-radius: $size + $border;
border-bottom-right-radius: $size + $border;
border: $border solid green;
border-left: 0;
}
.half-left-circle {
border-top-left-radius: $size + $border;
border-bottom-left-radius: $size + $border;
border: $border solid red;
border-right: 0;
}
Although this is exactly what I need, I was wondering if this can be achieved with just one html element (without pseudo elements of course :) ?
Here is a working snippet of what I'll do, using border:
% values instead of px for border-radius, it simplifies a lot!
border-color to add the correct color for each side.
transform: rotate(45deg); to turn it like you want.
body{
background: #ccc;
}
.halves-circle{
background: #fff;
height: 200px;
width: 200px;
border: 20px solid;
border-radius: 50%;
border-color: green green red red;
transform: rotate(45deg);
}
<div class="halves-circle">
⋅
⋅
⋅
We could use some CSS variables too, if you want to make many of them:
body{
background: #ccc;
}
.halves-circle{
background: #fff;
height: var(--size);
width: var(--size);
border: var(--border) solid;
border-radius: 50%;
border-color: green green red red;
transform: rotate(45deg);
}
#hc1{
--size: 100px;
--border: 20px;
}
#hc2{
--size: 60px;
--border: 30px;
}
#dot{ /* We can even do this! */
--size: 0px;
--border: 20px;
}
<div class="halves-circle" id="hc1"></div>
<div class="halves-circle" id="hc2"></div>
<div class="halves-circle" id="dot"></div>
Hope it helps.
Here is a more simple solution with only 2 gradient and less of code:
.circle {
margin:20px;
border-radius:50%;
width:200px;
height:200px;
background:
radial-gradient(circle at center,white 60%,transparent 60.5%),
linear-gradient(to right,red 50%,green 0);
}
body {
background-color:pink;
}
<div class="circle">
</div>
Please try this code
body {
background: #ccc;
}
.circle {
margin: 25px 0;
width: 200px;
height: 200px;
border-radius: 50%;
border: 12px solid transparent;
background-size: 100% 100%, 100% 50%,100% 100%, 100% 50%;
background-repeat: no-repeat;
background-image: linear-gradient(white, white),
linear-gradient(360deg, green 100%, lightgrey 100%),
linear-gradient(360deg, red 100%, lightgrey 100%);
background-position: center center, left top, right top, left bottom, right bottom;
background-origin: content-box, border-box, border-box, border-box, border-box;
background-clip: content-box, border-box, border-box, border-box, border-box;
transform: rotate(90deg);
}
<div class="circle">
</div>
Fiddle: http://jsfiddle.net/66r7nj4x/
I saw this question and answer: CSS Gradient arrow shape with inner shadow and gradient border and I'm looking to create the same thing but with an arrow on each side.
Here is what the final result would looks like:
I would do it in 3 steps:
create a normal rectangular element with a background gradient (e.g. from orange to red)
create a pseudo element ::before with a background color, the gradient is starting with (e.g. orange)
create a pseudo element ::after with a background color, the gradient is ending with (e.g. red)
Now you just need to position the pseudo elements properly and use the border property to create the triangle shape:
div {
position: relative;
display: inline-block;
text-transform: uppercase;
color: white;
height: 3em;
min-width: 10em;
line-height: 3em;
font-family: Arial;
font-size: 1.5em;
font-weight: bold;
text-align: center;
background: linear-gradient(to right, orange, red);
padding: 0 1em;
margin: 0 1em;
}
div::before,
div::after {
content: '';
position: absolute;
height: 0;
width: 0;
border-top: 1.5em solid transparent;
border-bottom: 1.5em solid transparent;
}
div::before {
left: -1em;
border-right: 1em solid orange;
}
div::after {
right: -1em;
border-left: 1em solid red;
}
<div>Exemple</div>
What about a solution with only gradient and no pseudo element:
.arrow {
text-transform: uppercase;
color: white;
width: 200px;
line-height: 3em;
font-family: Arial;
font-size: 1.5em;
font-weight: bold;
text-align: center;
background:
linear-gradient(to top left ,orange 50%,transparent 51%) top left /20px 50%,
linear-gradient(to bottom left ,orange 50%,transparent 51%) bottom left /20px 50%,
linear-gradient(to top right,red 50%,transparent 51%) top right /20px 50%,
linear-gradient(to bottom right,red 50%,transparent 51%) bottom right/20px 50%,
linear-gradient(to right, orange, red) 20px 0/calc(100% - 40px) 100% ;
background-repeat:no-repeat;
margin: 20px;
}
<div class="arrow">Exemple</div>
<div class="arrow">work with <br>2 lines</div>
And here is another one with clip-path:
.arrow {
text-transform: uppercase;
color: white;
width: 200px;
line-height: 3em;
font-family: Arial;
font-size: 1.5em;
font-weight: bold;
text-align: center;
background: linear-gradient(to right, orange, red);
margin: 20px;
clip-path: polygon(90% 0, 100% 50%, 90% 100%, 10% 100%, 0 50%, 10% 0);
}
<div class="arrow">Exemple</div>
<div class="arrow">work with <br>2 lines</div>
You Can also write css without using gradient background
Step 1: write html
<span class="right-arrow" style="
background-color: red;
width: 16%;
display: -webkit-box;
padding: 10px 10px;
color: #fff;
font-size: 16px;
font-weight: 600;
position: relative;
">
Example
</span>
Step 2: Write css
span{
background-color: red;
width: 180px;
display: -webkit-box;
padding: 10px 10px;
color: #fff;
font-size: 16px;
font-weight: 600;
position: relative;
}
span.right-arrow:after {
content: '';
width: 0;
height: 0;
border-top: 21px solid transparent;
border-left: 21px solid red;
border-bottom: 21px solid transparent;
position: absolute;
right: -21px;
top: 0;
}
Now it working fine
W3Schools has a great example of gradients in CSS: https://www.w3schools.com/css/css3_gradients.asp
background: linear-gradient(direction, color-stop1, color-stop2, ...)
background: linear-gradient(to right, red , yellow);
For the shape of your div, W3Schools also has a great page for creating geometric shapes: https://www.w3schools.com/howto/howto_css_shapes.asp
But to paste the same code twice:
div {
position: relative;
display: inline-block;
height: 3em;
min-width: 10em;
background: linear-gradient(to right, orange, red);
padding: 0 1em;
margin: 0 2em;
}
div::before,
div::after {
content: '';
position: absolute;
height: 0;
width: 0;
border-top: 1.5em solid transparent;
border-bottom: 1.5em solid transparent;
}
div::before {
left: -1em;
border-right: 1em solid orange;
}
div::after {
right: -1em;
border-left: 1em solid red;
}
i have bordered button (Non-div element, ). I need to get gradient color on the borders of my button. Now my button looks like this (In generally this is it):
.uibutton, uibutton:focus {
width: 120px;
height: 27px;
color: #007AFF;
outline: none;
border-radius: 3px;
border-width: 1px;
border-style: solid;
border-color: #007AFF;
background-color: transparent;
}
.uibutton:active {
width: 120px;
height: 27px;
color: #007AFF;
outline: none;
border-radius: 3px;
border-width: 2px;
border-style: solid;
background-color: transparent;
}
.uibutton:disabled {
width: 120px;
height: 27px;
color: #C7C7CC;
outline: none;
border-radius: 3px;
border-width: 1px;
border-color: #C7C7CC;
border-style: solid;
background-color: transparent;
}
<button class="uibutton">Hello World</button>
<button class="uibutton" disabled>Hello World</button>
I need gradient only in borders of button.
I'm so sorry, i'm idiot, just i confused in my code and how to write it.
Thanks for patience.
To add gradient background to button use code above or try CSS Gradient Generator.
.button {
width: 120px;
height: 27px;
outline: none;
border-radius: 3px;
box-sizing: border-box;
cursor: pointer;
}
.solid {
color: #fff;
border: none;
background: linear-gradient(150deg, #3acfd5 0%,#3a89d5 50%,#3a51d5 100%);
}
.thin {
border-left: none;
border-right: none;
border-top: 1px solid #1AD6FD;
border-bottom: 1px solid #1D62F0;
background-position: 0 0, 100% 0;
background-repeat: no-repeat;
background-size: 1px 100%;
background-color: transparent; /* removes button background */
background-image:
linear-gradient(to bottom, #1AD6FD 0%, #1D62F0 100%),
linear-gradient(to bottom, #1AD6FD 0%, #1D62F0 100%);
}
<button class="button solid">My button</button>
<button class="button thin">My button</button>