This question already has answers here:
Using percentage values with background-position on a linear-gradient
(2 answers)
Closed 2 years ago.
I used a button with a background effect. However, I don't understand how the background-position works.
the background position is set to the right then when I mouse over the button the background move to the left. However, I can't figure out why the "blue" seems to come from the left to the right, it's like if the background move to the right.
Shouldn't the background move to the left?
button {
color: white;
background: linear-gradient(to left, red 50%, blue 50%);
background-size: 200%;
background-position: right bottom;
border: none;
border-radius: unset;
width: 85px;
height: 35px;
transition: 2s ease;
cursor: pointer;
}
button:hover {
background-position: left bottom;
}
<button>Button</button>
Fiddle Link
The logic is simple, let's start by each property.
First you defined the gradient like this linear-gradient(to left, red 50%, blue 50%) which means that starting from the left we will have 50% of red then the remaining blue (50% too)
div {
height:50px;
width:100px;
background-image:linear-gradient(to left, red 50%, blue 50%)
}
<div>
</div>
Now you specified the background-size to be 200% which means that you will scale the size of the background by 2. To illustrate check the below code to see the intial background and the scaled one:
div {
height:50px;
width:100px;
background-image:linear-gradient(to left, red 50%, blue 50%)
}
div:nth-child(2) {
height:100px;
width:200px;
margin-top:20px;
}
<div>
</div>
<div>
</div>
But a background should always fit into the size of the element and in this case you will only see 1/4 of it (since we did a scale on both direction). And the background-position will decide about this. When you set it to right bottom you make the right bottom corner of the background to match the right bottom corner of the element like below:
So you will intially see the yellow part. And if you specify left bottom you will have this:
So it's like the yellow box is sliding from right to left OR the yellow box is fixed and the background is moving from left to right (this the behavior you see since the yellow box here is your button) .
The main reason about this movement is the overflow, so to change its position the background should move in the opposite direction unlike if the background-size was less than 100%. And if the background size was 100% you will see no movement because both position are equivalent!
Here is a working example with the 3 different cases:
div {
height:50px;
width:100px;
background-image:linear-gradient(to left, red 50%, blue 50%);
border:1px solid;
background-position:right bottom;
background-repeat:no-repeat;
transition:1s;
}
.d1 {
background-size:50%;
}
.d2 {
background-size:100%;
}
.d3 {
background-size:200%;
}
body:hover div{
background-position:left bottom;
}
I will move from right to left
<div class="d1">
</div>
I will not move !
<div class="d2">
</div>
I will move from left to right
<div class="d3">
</div>
Remove the background-position from your button or change the order like backgrond-position:left bottom and apply the right instead of left in your gradient and hover position like below.
button
{
color:white;
background: linear-gradient(to right, red 50%, blue 50%);
background-size: 200%;
border: none;
border-radius: unset;
width: 85px;
height: 35px;
transition: 2s ease;
cursor: pointer;
}
button:hover
{
background-position:right bottom;
}
Same I have added in the following snippet.
button
{
color:white;
background: linear-gradient(to right, red 50%, blue 50%);
background-size: 200%;
border: none;
border-radius: unset;
width: 85px;
height: 35px;
transition: 2s ease;
cursor: pointer;
}
button:hover
{
background-position:right bottom;
}
<button>
Button
</button>
Related
In this design I need the red background color of each cell partially changed say the first cell 100% second cell 100% and the third cell 50%.
Update: I have made a change where cell's background property is changed from red to
background: linear-gradient(to right, red 50%, white 51%)
but it has one problem that the edge on the right is not sharp and fades out gently blending into the white background, how to avoid that look?
Note: There are already few questions regarding hard-stop gradient creation which is why I didn't post my earlier comment as an answer but while searching for a duplicate I figured out there might be a better way to tackle your problem and hence posting the alternate approach as an answer.
Why is there a fade out and blend to white?
Let me get this out of the way before explaining the alternate approach (just for completeness sake). The gradient that you have defined would be interpreted by the UA as follows:
Since the first param is to right, the gradient starts at left (that is 0% is at left).
From 0% to 50% (that is, from left edge till half way), the color of the gradient is a solid red.
Red ends at 50% and white starts only at 51% as per gradient definition and so between 50 - 51% the color slowly changes from red to white (and blends with the white on the other side).
From 51% to 100% (that is, from slightly past half way till the right edge), the color is pure white.
This gap between 50% to 51% is generally used for diagonal (or angled) gradients where sharp stops result in jagged (uneven) edges but for normal horizontal or vertical gradients it won't be needed.
Now, I assume that you are trying to change the color stop points like below in order to get partial fill:
background: linear-gradient(to right, red 50%, white 50%); /* for a 50% fill */
background: linear-gradient(to right, red 75%, white 75%); /* for a 75% fill */
But there is a better way to do this than change the color stop points.
What is the better way and why?
A better option would be the one in the below snippet where the color never really changes. Gradient is just a solid red color always but we control it's size/width using background-size property. As you can see in the demo below, this is as effective as changing the color stop points.
This method is more advantageous when you want to animate/transition the background because the background-size is a transitionable property whereas the gradient image's color stop point change is not. You can see what I mean in the below demo. Just hover on each cell and see what happens.
.Row {
display: table;
width: 100%;
table-layout: fixed;
border-spacing: 10px;
}
.Column {
display: table-cell;
background: linear-gradient(red,red); /* use the color you need */
background-repeat: no-repeat; /* dont change */
border: 1px solid; /* just to show cell width */
}
.Column:nth-child(1) {
width:20%;
background-size: 100% 100%; /* change first value for width change */
}
.Column:nth-child(2) {
width:50%;
background-size: 75% 100%; /* change first value for width change */
}
.Column:nth-child(3) {
width:30%;
background-size: 50% 100%; /* change first value for width change */
}
/* just for demo */
.Column { transition: all 1s; }
.Column:nth-child(1):hover { background-size: 50% 100%; }
.Column:nth-child(2):hover { background-size: 100% 100%; }
.Column:nth-child(3):hover { background-size: 75% 100%; }
<div class="Row">
<div class="Column">C1</div>
<div class="Column">C2</div>
<div class="Column">C3</div>
</div>
How to change direction of the fill?
We can make the fill start from the right hand side of the cell instead of the left hand side by setting the background-position as right to the cells like in the below snippet:
.Row {
display: table;
width: 100%;
table-layout: fixed;
border-spacing: 10px;
}
.Column {
display: table-cell;
background: linear-gradient(red,red); /* use the color you need */
background-repeat: no-repeat; /* dont change */
background-position: right;
border: 1px solid; /* just to show cell width */
}
.Column:nth-child(1) {
width:20%;
background-size: 100% 100%; /* change first value for width change */
}
.Column:nth-child(2) {
width:50%;
background-size: 75% 100%; /* change first value for width change */
}
.Column:nth-child(3) {
width:30%;
background-size: 50% 100%; /* change first value for width change */
}
/* just for demo */
.Column { transition: all 1s; }
.Column:nth-child(1):hover { background-size: 50% 100%; }
.Column:nth-child(2):hover { background-size: 100% 100%; }
.Column:nth-child(3):hover { background-size: 75% 100%; }
<div class="Row">
<div class="Column">C1</div>
<div class="Column">C2</div>
<div class="Column">C3</div>
</div>
.Row {
display: table;
width: 100%;
table-layout: fixed;
border-spacing: 10px;
}
.Column {
display: table-cell;
background-color: red;
background: linear-gradient(to right, red, white);
}
.Column:nth-child(1) {
width:20%;
}
.Column:nth-child(2) {
width:50%;
}
.Column:nth-child(3) {
width:30%;
}
<div class="Row">
<div class="Column">C1</div>
<div class="Column">C2</div>
<div class="Column">C3</div>
</div>
Look this
I have trying to get the css gradient as like in the below bootstrap icon.
I just want two solutions from this code.
1.)How to make gradient color as like in icon(From top right to bottom left)?
2.)Vertical alignment of text within div(Possibility without using flex property)
Thanks in advance :)
div{
width:100px;
height:100px;
background: -webkit-linear-gradient(left, #2F2727, #1a82f7);
border-radius:4px;
}
div p{
color:white;
text-align:center;
text-transform:uppercase;
font-weight:bold;
font-size:42px;
}
<div>
<p>
b
</p>
</div>
Use to top right keyword for directing gradient to move from bottom left corner to top right corner.
background: linear-gradient(to top right, #2F2727, #1a82f7);
Use line-height equal to height.
More Information about css gradient is here.
div{
width:100px;
height:100px;
background: linear-gradient(to top right, #2F2727, #1a82f7);
border-radius:4px;
}
div p{
color:white;
text-align:center;
text-transform:uppercase;
font-weight:bold;
font-size:42px;
line-height: 100px;
}
<div>
<p>
b
</p>
</div>
try this:
div {
background: -webkit-linear-gradient(45deg, #2F2727, #1a82f7);
}
You should use radial gradient positioning - top right for this, like:
background: linear-gradient(
to top right,
#0F0437, #612D50
);
Have a look at the snippet below:
.box {
display: inline-block;
padding: 50px 70px;
font-size: 100px;
border-radius: 20px;
color: white;
background: linear-gradient(
to top right,
#0F0437, #612D50
);
}
<div class="box">B</div>
Hope this helps!
Use to top right for a diagonal angle (alternatively 45deg), and line-height equivalent to your height value to vertically center the letter.
Here it is with colors sampled from your image:
div {
background: linear-gradient(to top right, #080135 0%, #612d50 100%);
width: 100px;
height: 100px;
border-radius: 4px;
color: white;
font-family: sans-serif;
text-align: center;
font-weight: bold;
font-size: 60px;
line-height: 100px;
}
<div>B</div>
I'm struggling with responsive triangles - I need to create a triangle that fits the screen width but it's width doesn't change when screen width is made smaller.
try this
background-size: 100% 150px;
I come up with a solution that adds two triangles (each with a width of 50%) and by using a linear-gradient:
#triangle {
overflow: auto;
}
#triangle span {
width:50%;
height: 40px;
float: left;
}
#triangle span:first-child {
background: linear-gradient(to top left, orange 50%, transparent 50%);
}
#triangle span:nth-child(2) {
background: linear-gradient(to top right, orange 50%, transparent 50%);
}
<div id="triangle">
<span></span><span></span>
</div>
To make the triangle keep the initial width, you could add the following js:
var triangle = document.getElementById('triangle');
var width = triangle.offsetWidth;
triangle.style.setProperty('width', width+"px");
See the JSFiddle for a demo.
Please consider the following HTML and CSS :
HTML
<ul class="test1">
<li><div>Lorem ipsum</div></li>
<li><div>dolor sit amet</div></li>
</ul>
<ul class="test2">
<li><div>Lorem ipsum</div>
</li><li><div>dolor sit amet</div></li>
</ul>
CSS
.test1 div {height:100px;}
.test2 div {height:200px;}
li
{
display: inline-block;
width:100px;
transition:background-position 0.2s ease;
background-image: linear-gradient(to bottom, rgba(255,255,255,0) 50%, #F60 50%);
background-size: 100% 200%;
background-position : top left;
}
li:hover{color: #fff;background-position: bottom left;}
cfr jsfiddle
With a background being 200% of the height, and the top 50% of that background being transparent, that would mean that without hovering, all we can see is a transparent background. However, with this configuration I still can see a slight orange (#F60) line at the bottom, that being the bottom color of my "gradient" background.
If I want to fix this, I must specify background-size in pixels, and in that case I need to put background size as being (element size + 1 px)*2 . Could someone explain what causes this ? This is quite a problem as I would like to use this effect on blocks of a non-fixed height so percentage height is mandatory...
So here is a more involved answer that uses CSS animations: DEMO
Basically, I created colored DIV elements that have a 0% height. On hover of the parent li they grow to 100% height. The tricky part was preventing the return (shrink) animation from playing on page load: solved this by applying a white background to the overlaying text and fading it out after the initial page load completes (hideinit animation).
Added some classes and another DIV to the HTML markup:
<ul class="test1">
<li><div class="text">Lorem ipsum</div><div class="orange"></div></li>
<li><div class="text">dolor sit amet</div><div class="orange"></div></li>
</ul>
The updated CSS:
* I left off the webkit vendor prefixed styles for brevity, they are included in the Fiddle
li {
float: left;
list-style: none;
width:100px;
height: 100%;
position: relative;
}
li:hover div.orange{
animation: grow 1s 1 forwards;
}
li div.orange {
position: absolute;
bottom: 0;
background: orange;
height: 0%;
width: 100%;
z-index: -1;
animation: shrink 1s 1 forwards;
}
li div.text {
padding: 5px;
width: 100%;
height: 100%;
animation: hideinit 1s 1 forwards;
}
#keyframes grow {
from {height: 0%;}
to {height: 100%;}
}
#keyframes shrink {
from {height: 100%;}
to {height: 0%;}
}
#keyframes hideinit {
0% {background: white;}
98% {background: white;}
100% {background: none;}
}
I know that other answers already suggested increasing the background-size height to 201%, and that you had issues with items larger than, lets say 300px, but I tried 202% and was able to increase the size of the div up to 900px with no orange line appearing.
So in summary:
li {
display: inline-block;
width:100px;
transition:background-position 0.2s ease;
background-image: linear-gradient(to bottom, rgba(255,255,255,0) 50%, #F60 50%);
background-size: 100% 202%;
background-position : top left;
}
Best of luck!
to remove the line at the bottom you are having add:
li{
background-attachment: fixed;
}
JSFiddle
In response to dreamgt's comment I added some extra time to the animation. From:
transition:background-position 0.2s ease;
To:
transition:background-position 0.5s ease;
New JSFiddle
increase the height by an additional 1%
li {
display: inline-block;
width:100px;
transition:background-position 0.2s ease;
background-image: linear-gradient(to bottom, rgba(255,255,255,0) 50%, #F60 50%);
background-size: 100% 201%; /* <----------- increased height to 201% */
background-position : top left;
}
DEMO
So I've been at it for a while trying to achieve this one shape with CSS with no good solutions. I need this to be an image because this div may resize and I want it to stay intact. I've also attempted to create an SVG which did not work out very well, I've seen some people work with gradient to make shapes but I'm not able to find any good guide to point me in the right direction. Any help is appreciated :)
Using gradients with angles is not fit for your case because (as already pointed out by King King in comments) as the width the increases, the angle of the gradient (or) the color stop percentages need to be modified to maintain the shape. That is very tricky and so this method can be employed only when the shape has fixed dimensions.
However gradients can still be used with the to [side] [side] syntax because gradients defined using this syntax can adapt to variations in container sizes. In this method no pseudo-elements are used.
$(document).ready(function() {
$('#increase').on('click', function() {
$('.gradient').css('width', '300px').css('height', '500px');
})
})
div {
display: inline-block;
vertical-align: top;
height: 300px;
width: 100px;
margin: 10px;
color: beige;
transition: all 1s;
}
.gradient {
padding: 10px;
background: linear-gradient(to top right, transparent 50%, tomato 50%) no-repeat, linear-gradient(to top right, transparent 0.1%, tomato 0.1%) no-repeat;
background-size: 100% 100px, 100% 100%;
background-position: 0% 100%, 0% -100px;
}
/* Just for demo */
body {
background: -webkit-radial-gradient(50% 50%, circle, aliceblue, steelblue);
background: radial-gradient(circle at 50% 50%, aliceblue, steelblue);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="gradient">Some content</div>
<br>
<br>
<button id="increase">Increase Width & Height</button>
Note that it is better to make sure that the text doesn't flow into the slanted section of the shape because wrapping the text around to fit within the shape is not straight-forward.
I have attempted to make that in css as per ur image. http://jsfiddle.net/3zkme/- See if this could help. Thanks.
HTML
<div style="margin:30px">
<div class="trapezoid">
</div>
</div>
CSS
.trapezoid{
top: 150px;
vertical-align: middle;
border-bottom: 120px solid red;
border-left: 200px solid transparent;
border-top-left-radius:0px;
height: 0;
width: 150px;
transform:rotate(270deg);
-ms-transform:rotate(270deg); /* IE 9 */
-webkit-transform:rotate(270deg); /* Opera, Chrome, and Safari */
}
/* ---------- */
.trapezoid {
position:relative;
}
.trapezoid:after {
content:' ';
left:-14px;
top:10px;
position:absolute;
background:red;
border-radius:0px 0 0 0;
width:164px;
height:40px;
display:block;
}
You do not use a gradient for this, you just need to use a pseudo-element like :after.
Sample code:
#bookmark {
width: 50px;
height: 100px;
position: relative;
background: red;
}
#bookmark:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
border-bottom: 35px solid #FFF;
border-right: 50px solid transparent;
}
Live JSFiddle
If you want the shape to be filled in with a gradient, you can do that, too. Just add that to the CSS:
background: linear-gradient(to right, #ff0000 0%,#B00000 100%);