CSS apply gradient to right triangle shape with solid fill - html

I want to apply the same gradient to the triangle (class="triangle-right") as the rectangle (class="fillblue"). I have seen some other examples but they are not working for me. Combining both shapes and using a single class would be awesome too!
JS FIDDLE HERE!
CSS:
.fillblue {
background: rgb(208,228,247); /* Old browsers */
background: -moz-linear-gradient(top, rgba(208,228,247,1) 0%, rgba(115,177,231,1) 24%, rgba(10,119,213,1) 50%, rgba(83,159,225,1) 79%, rgba(135,188,234,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(208,228,247,1)), color-stop(24%,rgba(115,177,231,1)), color-stop(50%,rgba(10,119,213,1)), color-stop(79%,rgba(83,159,225,1)), color-stop(100%,rgba(135,188,234,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(208,228,247,1) 0%,rgba(115,177,231,1) 24%,rgba(10,119,213,1) 50%,rgba(83,159,225,1) 79%,rgba(135,188,234,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(208,228,247,1) 0%,rgba(115,177,231,1) 24%,rgba(10,119,213,1) 50%,rgba(83,159,225,1) 79%,rgba(135,188,234,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(208,228,247,1) 0%,rgba(115,177,231,1) 24%,rgba(10,119,213,1) 50%,rgba(83,159,225,1) 79%,rgba(135,188,234,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(208,228,247,1) 0%,rgba(115,177,231,1) 24%,rgba(10,119,213,1) 50%,rgba(83,159,225,1) 79%,rgba(135,188,234,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d0e4f7',
endColorstr='#87bcea',GradientType=0 ); /* IE6-9 */
height: 40px;
width: 100px;
display: inline-block;
float: left;
color: white;
text-align: center;
line-height: 40px;
font-weight: bold;
}
.triangle-right {
width: 0;
height: 0;
border-top: 20px solid transparent;
border-left: 40px solid lightblue;
border-bottom: 20px solid transparent;
float: left;
}
HTML:
<div class="fillblue">Step 1</div><div class="triangle-right"></div>

Part 1: Giving the triangle a gradient
The easiest way to achieve this would be to invert your triangle. and extend the length of the element with the gradient.
JSFiddle demo.
Inverting the triangle
Rather than giving the border-left on the triangle a solid colour, you want to give the top and bototm borders the colour (in this case we want to match the background colour, so lets make these white as that's the JSFiddle background colour):
.triangle-right {
...
border-top: 20px solid white;
border-left: 40px solid transparent;
border-bottom: 20px solid white;
}
If you're unsure what this achieves, here is an example of the triangle when the top and bottom borders are set to red instead of white:
Increasing the width of your gradient element
As your triangle is 40px wide, we need to increase the width of our gradient element by 40px. For this I've used padding to ensure the text remains in the same place:
.fillblue {
...
padding-right: 40px;
}
With the same red triangle we used above, this is what it now looks like:
Positioning the inverted triangle on top of our gradient element
Now we simply need to set a negative margin on our inverted triangle to make it appear on top of our gradient element:
.triangle-right {
...
margin-left: -40px;
}
Finally, using the red triangle again, our finished result looks like this:
Part 2: Combining both shapes into one element
To do this we can make use of the :after pseudo-element.
JSFiddle demo.
First off, lets modify our HTML:
<div class="fillblue">Step 1</div>
Now lets give our .fillblue element relative positioning. We do this so that we can absolutely position our triangle in the next step:
.fillblue {
...
position: relative;
}
Now we modify our previous .triangle-right styling to use this :after pseudo-element instead:
.fillblue:after {
width: 0;
height: 0;
border-top: 20px solid white;
border-left: 40px solid transparent;
border-bottom: 20px solid white;
}
Finally we give it the new properties to position it correctly and actually make it display:
.fillblue:after {
...
content: '';
position: absolute;
top: 0;
right: 0;
}

I wanted to suggest using border-image: linear-gradient(...); but then I looked up https://developer.mozilla.org/en-US/docs/Web/CSS/border-top and saw that it's not possible to apply a border-image to just 1 of the borders, and then make the other borders transparent. There's also no border-left-image, so that won't work either. Since border-image is a relatively new addition to CSS (it's part of CSS3), it's not integrated in CSS as well as the other border styles. That's why doing this with borders is not possible. (It looks like this (simple webkit-only demo) if you do try to add a border-image, and then try to override it with transparent borders - it doesn't work)
Assuming you want to keep using borders to create your triangle, I would say this is not possible.
The only way you could make it work then is by changing the div to a square that's got a diagonal gradient, and is rotated 45 degrees via CSS transforms. That would end up being something like this:
.triangle-right {
display:inline-block;
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,rgba(208,228,247,1)), color-stop(24%,rgba(115,177,231,1)), color-stop(50%,rgba(10,119,213,1)), color-stop(79%,rgba(83,159,225,1)), color-stop(100%,rgba(135,188,234,1))); /* Chrome,Safari4+ */
/* etc. */
width:28px; /* ~ sqrt(2*40^2)/2 */
height:28px;
-webkit-transform: rotate(45deg);
/* etc. */
margin-top:6px;
margin-left:-14px;
}
Demo
Keep in mind that that is probably not the best solution, since it'd rely purely on transforms, which are not supported in every browser, and there are no good fallbacks for it. It does have one advantage over James Donnely's solution, which is that it keeps its soft borders instead of becoming jagged.
It does have other significant downsides though, namely that you're relying on fixing its position with transform and margin. It is possible other browsers don't handle this exactly the same as Chrome does, and therefore show your triangle differently. They should all show it the same way, but there's always a chance some browser decides to do things slightly differently.
Explanation of the code: The /* etc. */ stands for the other browser prefixes, the width and height are 28px because that's the height of the rotated square, its diagonal length (sqrt(width^2 + height^2)). This is also the reason the margin-left needs to be -14px (half of this diagonal length): it needs to move 14 pixels to the left, so that its corner is moved over the .fillblue element.
As was asked below in the comments, it is also possible to scale the triangle to be wider (or slimmer). This can be done by simply changing the transformation to scale(2, 1) rotate(45deg) so that it applies the stretching and rotating in the right order. A demo of this can be found at http://jsfiddle.net/x61Lyar0/2/.
PS: If you want your arrow to be less pointy, you can apply border-radius: 0 2px 0 0; (or border-top-right-radius: 2px) to smooth it out just a little bit.

Related

How can I reflect contents downwards [duplicate]

Is there similar property to -webkit-box-reflect for the mozilla and other browsers? I could not find on google which other browsers have support for this. So if someone can tell me or give me link, that would be really nice.
This is possible with not only webkit (latest chrome or safari) but also in latest firefox.
Here is the example: http://codepen.io/jonathan/pen/pgioE
HTML:
<div id="someid">
<img src="image url" />
<div/>
CSS (webkit):
#someid {
/* need some space for the reflection */
margin-bottom: 120px;
/* the gradient makes the reflection fade out */
-webkit-box-reflect: below 0px -webkit-linear-gradient(bottom, rgba(255,255,255,0.3) 0%, transparent 40%, transparent 100%);
}
CSS (Firefox - Gecko):
#someid {
position: relative;
/* need some space for the reflection */
margin-bottom: 120px;
}
#someid:before {
content:""; /* needed or nothing will be shown */
background: -moz-linear-gradient(top, white, white 30%, rgba(255,255,255,0.9) 65%, rgba(255,255,255,0.7)) 0px 0px, -moz-element(#someid) 0px -127px no-repeat;
-moz-transform: scaleY(-1); /* flip the image vertically */
position:relative;
height:140px;
width: 360px; /* should be > image width + margin + shadow */
top: 247px;
left:0px;
}
Firefox uses -moz-element to do the reflections (https://developer.mozilla.org/en-US/docs/CSS/element), whereas webkit uses a proprietary vendor prefix for reflections.
I hope this helps!
The -webkit-box-reflect property is only supported by webkit browsers, namely Chrome and Safari. As it is a proprietary webkit property, there is no equivalent for other browsers.
The alternative would be to use javascript to create a mirror element with faded opacity.

How to use css property linear-gradient to gradually change color from red to yellow to green?

I want to create a legend using html, css which contains change of color gradient from green to yellow to red. I have tried using linear gradient property of css. However, what I got so far is given below:
#color_range {
height: 280px;
width: 40px;
background: linear-gradient(to top, #DAECB8 0%, #E33127 100%);
}
<div id="color_range"></div>
My code for color gradient
I need a figure like this:
How can I make a legend like above?
Simply change: background: linear-gradient(to top, #DAECB8 0%, #E33127 100%);
To: background: linear-gradient(red,yellow,green);
You can also change it to: linear-gradient(to top, green,yellow,red); but I don't think that to top is necessary
#color_range {
height: 280px;
width: 40px;
background: linear-gradient(red,yellow,green);
}
<div id="color_range"></div>
To understand how linear-gradient works in CSS please read: CSS Gradients
Also take a look at this page that can be helpful when using CSS gradients: https://www.colorzilla.com/gradient-editor/
You can try this.
#color_range{
height:280px;
width:40px
background:linear-gradient(red,yellow,green);
}
You can also use the color codes for these colors .

When creating a circle sector in css, a slim line is visible in Chrome and IE

I am a novice when it comes to css and am creating a custom audio player using a mixture of css and jquery. The progress bar of this audio player is a ring, which uses circle sectors to display progress. The sector is created using linear-gradient, like so:
background-image:
linear-gradient(-75deg, black 50%, transparent 50%),
linear-gradient(90deg, transparent 50%, white 50%);
In firefox this works perfectly, but in both chrome and ie, a very slim white line is visible on the outside of half of the circle, presumably where part of the linear-gradient is supposed to cover.
I have created a jsfiddle that displays the issue, https://jsfiddle.net/9dagsrzz/
Is there something that I am doing wrong that causes this, or is there a fix I can apply that removes this line?
Thank you for your time.
Edit - it has been over a month and I thought I would update and say that I have still not been able to find a complete solution to this problem. The best way of dealing with the issue is to include a covering border, as suggested by Pustur below.
Samiskeen,
I'm no CSS expert either but I do know that each browser has its required prefixes when dealing with gradients:
-moz- is for Mozilla Firefox
-webkit- is for Apple Safari, Google Chrome, and also for ios and Android
-o- is for Opera
-ms- is for Microsoft IE and presumably Edge
You can have all of these present on their own line and the browser will pick the correct one.
Example:
background-image:
-moz-linear-gradient(-75deg, black 50%, transparent 50%),
-moz-linear-gradient(90deg, transparent 50%, white 50%);
-webkit-linear-gradient(-75deg, black 50%, transparent 50%),
-webkit-linear-gradient(90deg, transparent 50%, white 50%);
-o-linear-gradient(-75deg, black 50%, transparent 50%),
-o-linear-gradient(90deg, transparent 50%, white 50%);
-ms-linear-gradient(-75deg, black 50%, transparent 50%),
-ms-linear-gradient(90deg, transparent 50%, white 50%);
The website http://caniuse.com lists the major CSS rules, attributes and whether browser specific versions are required.(Nixon, p. 439).
Play around with the prefixes, they should help correct your problem.
Good Luck.
Jim
Not sure if this is a definitive solution or the best, but it seems to work fine at least on chrome.
HTML:
<!-- divs instead of spans -->
<div id="container">
<div id="position_indicator"></div>
<div id="inside"></div>
</div>
CSS:
#container {
width: 100px;
height: 100px;
background-color: black;
position: relative;
padding: 20px;
}
#inside {
width: 90px;
height: 90px;
background-color: black;
border-radius: 100%;
position: absolute;
margin-left: 5px;
margin-top: 5px;
}
#position_indicator {
border: 1px solid black; /* Fix the border issue! */
margin-left: -1px; /* Compensate for the new border */
margin-top: -1px; /* Compensate for the new border */
width: 100px;
height: 100px;
border-radius: 100%;
position: absolute;
background-color: black;
background-image: linear-gradient(-75deg, black 50%, transparent 50%), linear-gradient(90deg, transparent 50%, white 50%);
}
Fiddle

using css, how to create a white circle within a transparent div?

I wish to create a white circle with fuzzy edges contained within a transparent div by using css gradients.
With the z-index higher than the body and absolute positioning I should be able to move this over any part of the page and "white-out" everything beneath the circle.
I have tried my favorite gradient generators, but they haven't worked.
<div id="circle"></div>
css
#circle {
width: 50px;
height: 50px;
-webkit-border-radius: 25px;
-moz-border-radius: 25px;
border-radius: 25px;
}
Try using http://www.colorzilla.com/gradient-editor/.
Here's one I made using their tool: (Set the orientation to radial)
http://www.colorzilla.com/gradient-editor/#ffffff+24,ffffff+59&1+31,0+34;Custom
To make the edges more fuzzy, drag the second opacity stop further from the white - and vice versa.
try white background with box-shadow's inset property to create fuzzy edges. Although I don't get what fuzzy means to you. If you have a specific color in mind for the edges, I might be able to give you the code.
Used the gradient suggested by George Reith.
CSS
#white-circle {
background: radial-gradient(ellipse at center center , #FFFFFF 24%, #FFFFFF 31%, rgba(255, 255, 255, 0) 34%, rgba(255, 255, 255, 0) 71%) repeat scroll 0 0 transparent;
height: 100px;
left: 150px;
position: absolute;
top: 0;
width: 100px;
z-index: 1;
}
Here is the outcome: http://jsbin.com/avipih/1
I guess that radial gradient is an overkill for such purpose. Here's much simplier solution with better browser support: http://cdpn.io/yrJji

Simulate image "overlay" with CSS

Basically I'm trying to simulate Photoshop's image overlay thing using images and CSS for a menu.
There are 2 versions of the menu background image: one is the normal state (pink), and one the active state (blue). The entire menu is wrapped in a DIV with the normal (pink) image as background.
How can I make it so each active menu link uses the corresponding slice of the blue image?
Like this:
My code so far
Do you think this is possible with CSS?
CSS Only solution for modern browsers:
ul {
background-color:#ff00ff;
background-image: -moz-radial-gradient(50% 50%, ellipse closest-side, #ffffff 0%,#ff00ff 110%);
background-image: -webkit-radial-gradient(50% 50%, ellipse closest-side, #ffffff 0%,#ff00ff 110%);
background-image: -o-radial-gradient(50% 50%, ellipse closest-side, #ffffff 0%,#ff00ff 110%);
background-image: -ms-radial-gradient(50% 50%, ellipse closest-side, #ffffff 0%,#ff00ff 110%);
background-image: radial-gradient(50% 50%, ellipse closest-side, #ffffff 0%,#ff00ff 110%);
height:50px;
width:400px;
margin:0;
padding:0;
border-radius:25px;
overflow:hidden;
}
li {
width:100px;
height:50px;
float:left;
}
li:hover {
background-color:rgba(0,0,255,0.2);
}
Click to see a working demo: http://jsfiddle.net/AlienWebguy/ZLg4B/
If you need to support older browsers and can't use css3, there is a number of ways to do this. One of them:
You can cut out the blue image of the entire thing (you can actually make it wider)
then
li.active {
background: url('path/to/yourImage.png') no-repeat -50px 0;
/* 50px or however wide that rounded tip is */
}
li.active.first {
background-position: left top;
}
li.active.last {
background-position: right top;
}
/* you'll need to add 'active', 'first' and 'last' classes accordingly. */
Are you ever going to have links at the rounded parts? If not, you could just take a pixel-wide slice of the blue image and set that to the :hover state background with repeat-x.
There are definitely other ways to do this but this is the most straightforward IMHO.
Edit: After seeing your fiddle, perhaps this isn't the case. I would consider using JavaScript to calculate appropriate x-offsets for each link, and using a slice of the overlay image in that way. Or you could just make the first link a "special case" and use a generic different-color background for the rest of the links.