Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS gradient colour stops from end in pixels

I'm working on a HTML/CSS/JS project where the app is a fixed size and elements must be positioned precisely, based on the designs. Because the window size is fixed, I can easily work with pixel dimensions in CSS and not worry about resizing the browser. I also have the luxury of not worrying about IE or Opera: the app must work in webkit and firefox only.

In a few places, I need to have a gradient background going over specific number of pixels. This would be easily accomplished with something like

background-image: linear-gradient(to top, #666666, #000000 60px);

(and its -webkit- and -moz- counterparts.) This does the trick for most elements. However there are a couple where I need to have the top and bottom pixel positions for colour stops. If these were percentage points, then it could be done with something like:

background-image: linear-gradient(to top, #666666, black 60px, transparent 60px, transparent 90%, black 90%, #666666);

(from grey to black over 60px, then transparent and then black to grey over the last 10%). However I need to accomplish the same with pixels, as the element in question is sized differently at different times. I'd like to avoid having to use JS to re-apply the gradient at different dynamically calculated percentage points if needed.

So, my question: is there a way to specify a colour stop x pixels (not percentage) from the end?

like image 630
Aleks G Avatar asked Dec 04 '12 17:12

Aleks G


People also ask

What is color stop in gradient?

Color stops are the colors you want to render smooth transitions among. This value consists of a color value, followed by an optional stop position (a percentage between 0% and 100% or a length along the gradient axis).

Can we use more than 2 color in gradient CSS?

To create the most basic type of gradient, all you need is to specify two colors. These are called color stops. You must have at least two, but you can have as many as you want.

How do you put a linear gradient on an image in CSS?

CSS Linear Gradients To create a linear gradient you must define at least two color stops. Color stops are the colors you want to render smooth transitions among. You can also set a starting point and a direction (or an angle) along with the gradient effect.


3 Answers

I just came over this via search engine, i think the best solution was already given by vals with using multiple background images - but instead of using background-size and background-position i think it's a lot more flexible and stable to use alpha colors here (with rgba()), like in the example below:

background-image:
    /* top gradient - pixels fixed */
    linear-gradient(to bottom, rgb(128,128,128) 0px,rgba(128,128,128,0) 16px), 
    /* bottom gradient - pixels fixed */
    linear-gradient(to top, rgb(128,128,128) 0px, rgba(128,128,128,0) 16px),  
    /* background gradient - relative */
    linear-gradient(to bottom, #eee 0%, #ccc 100%) ;

This gives me exactly the behaviour I was initially searching for. :)

Demo: http://codepen.io/Grilly86/pen/LVBxgQ

like image 153
grilly Avatar answered Oct 08 '22 07:10

grilly


It works with calc(), but unfortunately not in MS browsers:

First row of each pairs has the solution with 2 background stacked, 2nd row has calc in use. Does not work with Internet Explorer and Edge browsers.

div {
  margin-left: auto;
  margin-right: 0;
  width: 200px;
  height: 20px;
  animation: sweep 5s ease-in-out alternate infinite;
  text-align: center;
  color: white;
  font-family: sans-serif;
  font-weight: bold;
  line-height: 20px;
  will-change: width;
}

div:nth-child(odd) {
  background-image: linear-gradient(to right, red, green 100px, transparent 101px), linear-gradient(to left, red, green 100px);
  border-bottom: 1px solid gray;
}

div:nth-child(even) {
  background-image: linear-gradient(to right, red, green 100px, green calc(100% - 100px), red);
  margin-bottom: 10px;
}

div:nth-child(n+3) {
  width: 300px;
}

div:nth-child(n+5) {
  width: 400px;
}

div:nth-child(n+7) {
  width: 500px;
}

div:nth-child(n+9) {
  width: 600px;
}

@keyframes sweep {
  100% {
    width: 600px;
  }
}
<div> 200 </div>
<div></div>
<div> 300 </div>
<div></div>
<div> 400 </div>
<div></div>
<div> 500 </div>
<div></div>
<div> 600 </div>
<div></div>
like image 2
yunzen Avatar answered Oct 08 '22 07:10

yunzen


I don't think this is possible, but overlaying 2 objects, one with opaque pixels from bottom and the other with pixels from top, would still avoid using JS

.background {
    position: absolute;
    background-image: linear-gradient(to top, #666666, black 60px, transparent 60px);
}
.overlay {
    position: relative;
    background-image: linear-gradient(to bottom, #666666, black 60px, transparent 60px);
}
like image 1
po228 Avatar answered Oct 08 '22 06:10

po228