Making multiple gradients using Less CSS - css

This is the first project I've used Less on, I want to make a series of buttons that have the same general structure but have different gradiated colours applied to them.
I have my default button style:
.button-regular (#origin: top, #start: #d2d2d2, #middle: #7a7a7a, #stop: #4d4d4d, #fallback: #3f4c6b, #border: #3c3c3c;) {
border-radius: 3px; color: #white; font-size: 13px; line-height: 18px; height: 36px; font-weight: normal; padding: 8px 15px 8px 15px; text-align: center;
background: #fallback;
background: -moz-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #start), color-stop(6%, #middle), color-stop(100%, #stop));
background: -webkit-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: -o-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: -ms-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: linear-gradient(to bottom, #start 0%, #middle 6%, #stop 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#middle', endColorstr='#stop', GradientType=0);
border: 1px solid #border;
}
I want to overwrite the colours for each new instance of the button using something like the below:
input.lightBlue {
.button-regular(top, #bfeef8, #40cdeb, #00bce4, #3f4c6b, #00b0d5;);
}
But when I create a button:
<input class="lightBlue" type="submit" value="Search">
The original (grey) colours still show. Is there a reason why the colours aren't overwritten using my new colours in this new button instance, and is there a better way to acheive what I'm attempting?
I'm using less.js to compile in-browser if that makes any difference.

What you have there should work alright, you just need to
fix a typo:
there is a semicolon (;) (after the last color) too much in your class definition
input.lightBlue {
.button-regular (top, #bfeef8, #40cdeb, #00bce4, #3f4c6b, #00b0d5);
}
you call for a variable #white in the mixin, where you just need to make sure you define it beforehand, or else just write white instead.
some additional suggestions:
(I used some random settings for illustration).
You could do something like this
<input class="button default" type="submit" value="Search">
<input class="button green" type="submit" value="Search">
<input class="button red" type="submit" value="Search">
where you have a button class to define the general button appearance. Dunno, maybe something like this:
.button {
display: inline-block;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: 14px/100% Arial, Helvetica, sans-serif;
padding: .5em 2em .55em;
text-shadow: 0 1px 1px rgba(0,0,0,.3);
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.2);
box-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.button:active {
position: relative;
top: 1px;
}
and in LESS you make some mixins for the color gradients. Something like this:
.gradient-mixin (#origin, #start, #middle, #stop, #fallback, #border) {
background: #fallback;
background: -moz-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #start), color-stop(6%, #middle), color-stop(100%, #stop));
background: -webkit-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: -o-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: -ms-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: linear-gradient(to bottom, #start 0%, #middle 6%, #stop 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#middle', endColorstr='#stop', GradientType=0);
border: 1px solid #border;
}
.button-make (#name:"default", #origin: top, #start: #d2d2d2, #middle: #7a7a7a, #stop: #4d4d4d, #fallback: #3f4c6b, #border: #3c3c3c;) {
#classname: ~"#{name}";
.#{classname} {
.gradient-mixin (#origin, #start, #middle, #stop, #fallback, #border);
&:hover {
.gradient-mixin(#origin, lighten(#start,10%), lighten(#middle,10%), lighten(#stop,10%), lighten(#fallback,10%), #border);
}
&:active {
.gradient-mixin (#origin, darken(#start,10%), darken(#middle,10%), darken(#stop,10%), darken(#fallback,10%), #border);
}
}
}
and then you call them for each color ... which will build your classes for each color for the buttons:
.button-make;
.button-make ("green", top, #7db72f, #87d918, #4e7d0e, #7db72f, #538312);
.button-make ("red", top, #ed1c24, #e93a3f, #aa1317, #ed1c24, #980c10);
here is a jsfiddle example of the output.
But instead of defining all colors in the gradient by hand you can also make a more general mixin in LESS, that takes one color and transforms it to colors you use for #stop,#start,#border,... by using lighten, darken and other color operations.

What I understand about this is that you want to overwrite your CSS with these buttons. All you have to do is create divs for your buttons or whatever else you are trying to do. I'll show an example here:
HTML
<input class="lightblue" type="submit" value="Search" style="/*style goes here*/">
CSS:
.lightblue {
border-radius: 3px; color: #white; font-size: 13px; line-height: 18px; height: 36px; font-weight: normal; padding: 8px 15px 8px 15px; text-align: center;
background: #fallback;
background: -moz-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #start), color-stop(6%, #middle), color-stop(100%, #stop));
background: -webkit-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: -o-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: -ms-linear-gradient(#origin, #start 0%, #middle 6%, #stop 100%);
background: linear-gradient(to bottom, #start 0%, #middle 6%, #stop 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#middle', endColorstr='#stop', GradientType=0);
border: 1px solid #border;
}
So the point that I'm trying to make is that you just need a style for buttons. If you want to override this, then put the style in the HTML where I've shown. Hope this helps you out.

Related

Add background property without overwriting the existing one

I have an issue with CSS.
I have a gradient, with more than one instruction to make it compatible with any browser.
background: no-repeat 20px center url("./img/pc.png"), -webkit-gradient(linear, left top, left bottom, from(#000000), to(#111111));
background: no-repeat 20px center url("./img/pc.png"), -webkit-linear-gradient(top, #000000, #111111);
background: no-repeat 20px center url("./img/pc.png"), -moz-linear-gradient(top, #000000, #111111);
background: no-repeat 20px center url("./img/pc.png"), -ms-linear-gradient(top, #000000, #111111);
background: no-repeat 20px center url("./img/pc.png"), -o-linear-gradient(top, #000000, #111111);
background: no-repeat 20px center url("./img/pc.png"), linear-gradient(to bottom, #000000, #111111);
As you can see, there is also an image for the background. Now, imagine if this image was inline. It would be an enormous waste of space to copy and paste it many times.
Is there a way to do sometning like this:
background: no-repeat 20px center url("./img/pc.png");
background: linear-gradient(to bottom, #000000, #111111);
But without overwriting (and destroying) the first property (image) with the second call (gradient)?
Thanks
If you don't want to repeat yourself use CSS variable:
:root {
--image:url("https://lorempixel.com/400/200/") center/100px no-repeat
}
.box {
height:200px;
background: var(--image), -webkit-gradient(linear, left top, left bottom, from(#000000), to(#111111));
background: var(--image), -webkit-linear-gradient(top, #000000, #111111);
background: var(--image), -moz-linear-gradient(top, #000000, #111111);
background: var(--image), -ms-linear-gradient(top, #000000, #111111);
background: var(--image), -o-linear-gradient(top, #000000, #111111);
background: var(--image), linear-gradient(to bottom, #000000, #111111);
}
<div class="box">
</div>
<div class="box" style="--image:url(https://lorempixel.com/400/400/) center/100px no-repeat ">
</div>
Use an :after psuedo-element to add the gradient on top the image background.
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
div {
width: 100%;
height: 100%;
background: no-repeat center center url(http://via.placeholder.com/350x150);
position: relative;
}
div:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, transparent, #111111);
}
<div></div>
Both linear-gradient and url affect the background-image, so no, you cannot use those two in conjunction; the second one would overwrite the first.
When you combine these two rules in the following shorthand order:
background: no-repeat 20px center url("./img/pc.png");
background: linear-gradient(to bottom, #000000, #111111);
Only the background-image of the second rule gets applied; the other rules from the first shorthand rule get ignored:
background-image: linear-gradient(rgb(0, 0, 0), rgb(17, 17, 17));
background-position-x: initial;
background-position-y: initial;
background-repeat-x: initial;
background-repeat-y: initial;
However, you can cause these additional rules to apply by specifying the gradient as the background-image manually:
background-image: url(./img/pc.png); /* Only rule to get overriden */
background-image: linear-gradient(rgb(0, 0, 0), rgb(17, 17, 17));
background-position-x: 20px;
background-position-y: center;
background-repeat-x: no-repeat;
background-repeat-y: no-repeat;
This way your background-position-x, background-position-y, background-repeat-x and background-repeat-y rules can be applied in conjunction with your gradient... though it is impossible to have both of your background-url rules apply to the same element at the same time.
To have both the image and the gradient show up, I would recommend making use of two elements positioned on top of each other with position: absolute, and applying one background-image to each. The gradient would go on top, and be transparent so that the background image can be seen.
This can be seen in the following:
div {
width: 100px;
height: 100px;
position: absolute;
}
.background {
background-image: url("http://placehold.it/100");
}
.gradient {
background-image: linear-gradient(to bottom, transparent, #111111);
}
<div class="background"></div>
<div class="gradient"></div>

How to add gradient background to text (multiple lines)

I found this jsfiddle on the internet. Does anyone of you know how I can change the background color from white into a gradient color? The gradient color should "restart" on each new line. Please see desired wish on "example 2" in this image: http://www.managers.dk/css-text-background.jpg
http://jsfiddle.net/omgmog/g3MQf/
h1 { width:480px; font:bold 36px sans-serif; letter-spacing:-1px; color:#000; }
h1 {
background: #fff;
display:inline;
white-space: pre-line;
position: relative;
padding: 9px 0;
line-height: 54px;
-moz-box-shadow: -20px 0 0 #fff, 20px 0 0 #fff;
-webkit-box-shadow: -20px 0 0 #fff, 20px 0 0 #fff;
box-shadow: -20px 0 0 #fff, 20px 0 0 #fff;
}
Thanks!
I don't believe there is a way to accomplish what you are looking for in plain CSS since there is no "new line" selector. The only way to do it is to explicitly define each new line by wrapping the text into a span element.
body
{
padding:50px;
background:#fff;
}
h1
{
width:480px;
font:bold 36px sans-serif;
letter-spacing:-1px;
color:#000;
display:inline;
white-space: pre-line;
position: relative;
padding: 9px 0;
line-height: 54px;
}
h1 span
{
background: -moz-linear-gradient(left, rgba(148,199,247,1) 0%, rgba(32,124,229,1) 100%);
background: -webkit-gradient(left top, right top, color-stop(0%, rgba(148,199,247,1)), color-stop(100%, rgba(32,124,229,1)));
background: -webkit-linear-gradient(left, rgba(148,199,247,1) 0%, rgba(32,124,229,1) 100%);
background: -o-linear-gradient(left, rgba(148,199,247,1) 0%, rgba(32,124,229,1) 100%);
background: -ms-linear-gradient(left, rgba(148,199,247,1) 0%, rgba(32,124,229,1) 100%);
background: linear-gradient(to right, rgba(148,199,247,1) 0%, rgba(32,124,229,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#94c7f7', endColorstr='#207ce5', GradientType=1 );
}
header
{
width: 550px;
}
<body>
<header>
<h1>
<span>Some dynamic HTML text on</span>
<span>several lines with a background</span>
<span>that suits well and some margins</span>
<span>around it.</span>
</h1>
</header>
</body>
Please check my updated answer.
I have added background-attachment:fixed; to get the desired output.
h1 { width:480px; font:bold 28px sans-serif; letter-spacing:-1px; color:#fff;
background: -webkit-linear-gradient(left, #085d9d 0%, #92d5ff 100%);
background: -moz-linear-gradient(left, #085d9d 0%, #92d5ff 100%);
background: -o-linear-gradient(left, #085d9d 0%, #92d5ff 100%);
background: linear-gradient(to right, #085d9d 0%, #92d5ff 100%);
background-attachment:fixed;
display: inline;
line-height: 50px;
padding: 7px 3px;
white-space: pre-wrap;
}
<h1>Some dynamic HTML text on several lines with a background that suits well and some margins around it.</h1>
If you're unfamiliar with gradients there are tools out there that will help you do it more visually. One such tool is http://www.colorzilla.com/gradient-editor/ which will allow you to visually build your gradient, then click a button to copy that code to be pasted into your CSS file. It will provide you with browser safe options for most of the main browsers. simply add it to your background CSS code and it should produce the result you requested.
I hope this helps!

CSS Gradient on Android

I'm trying to make this gradient to work on Android but I don't know the right css option.
HTML:
<div class="bottom-logo">
<div id="logo" class="logo-menu-green">blaa</div>
</div>
Css:
#logo{
font-family: "Lato", "Open Sans";
font-weight: bold;
position: absolute;
z-index: 999;
background: #6699cc;
background: -moz-linear-gradient(left, #6699cc 0%, #3399cc 20%, #009999 37%, #009966 52%, #999999 68%, #9933cc 73%, #990099 90%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#6699cc), color-stop(20%,#3399cc), color-stop(37%,#009999), color-stop(52%,#009966), color-stop(68%,#999999), color-stop(73%,#9933cc), color-stop(90%,#990099));
background: -webkit-linear-gradient(left, #6699cc 0%,#3399cc 20%,#009999 37%,#009966 52%,#999999 68%,#9933cc 73%,#990099 90%);
background: -o-linear-gradient(left, #6699cc 0%,#3399cc 20%,#009999 37%,#009966 52%,#999999 68%,#9933cc 73%,#990099 90%);
background: -ms-linear-gradient(left, #6699cc 0%,#3399cc 20%,#009999 37%,#009966 52%,#999999 68%,#9933cc 73%,#990099 90%);
background: linear-gradient(to right, #6699cc 0%,#3399cc 20%,#009999 37%,#009966 52%,#999999 68%,#9933cc 73%,#990099 90%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6699cc', endColorstr='#990099',GradientType=1 );
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
I tried but it doesn't work. Thank you.
EDIT:
A solution would be to use SVG filters.
Only solution i can think of after my fair share of issues with Android.
Replicate the gradient into a graphical tile, and merely change the following.
Took your code and imported it here.
Visual file
CSS
#logo{
font-family: "Lato", "Open Sans";
font-weight: bold;
position: absolute;
z-index: 999;
background-image: url(img/thegradient.jpg);
background-repeat: no-repeat;
}
Also the gradient didn't even appear until i removed these two lines
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
If this is not what you were looking for i recommend using the javascript method introduced in the comments on your post.
Best of luck.

How to have 2 colors in TD background with CSS

I have an event calendar that made use of CSS to paint the background red, to hilight holidays:
.holiday {
text-align: center;
font-size: 11px;
font-weight: bold;
color: #ffffff;
background-color: #da1030;
border: 1px solid black;
height:20px;
width:20px;
}
For special events, I used purple as the background:
.sp_event {
text-align: center;
font-size: 11px;
font-weight: bold;
color: #ffffff;
background-color: purple;
border: 1px solid black;
height:20px;
width:20px;
}
Things work okay:
This to hilight holiday on 1st of this month
1
This to indicate special event that falls on the 5th of this month
5
BUT there are times that my special event falls on a holiday. So in this case, I want to have the TD background to be painted in red and purple, dividing the TD in 2 equal halves. Could you guys show me how this can be done with CSS? TIA.
You could accomplish this with a pseudoelement in the td that takes up half of the width and is positioned on the right to get the full width/height.
.holiday.sp_event:after {
position: absolute;
width: 50%;
height: 100%;
right: 0;
background-color: red;
content: "";
top: 0;
}
http://jsfiddle.net/rX7gd/
Here is a working fiddle
One solution people use is to use a gradient:
background: #a423b2; /* Old browsers */
background: -moz-linear-gradient(left, #a423b2 0%, #bf24b4 49%, #da1030 50%, #da1030 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#a423b2), color-stop(49%,#bf24b4), color-stop(50%,#da1030), color-stop(100%,#da1030)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, #a423b2 0%,#bf24b4 49%,#da1030 50%,#da1030 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, #a423b2 0%,#bf24b4 49%,#da1030 50%,#da1030 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(left, #a423b2 0%,#bf24b4 49%,#da1030 50%,#da1030 100%); /* IE10+ */
background: linear-gradient(to right, #a423b2 0%,#bf24b4 49%,#da1030 50%,#da1030 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a423b2', endColorstr='#da1030',GradientType=1 ); /* IE6-9 */
I created this using this tool. It is cross-browser complaint (IE6 up) and requires you to make no structural changes to your HTML at all.

CSS3 iOS badge text not vertically centering

I have setup a CSS profile to create an iOS type notification badge. All is working well except the inner font vertical alignment. Firefox renders the inner text perfectly centered, however webkit browsers (safari, chrome, etc) act as though there is a padding-top applied pushing the font too far from the top. Here is a fiddle for a demo: http://jsfiddle.net/F5wdp/
And here is the code:
.alert-notify-circle{
float:left;
background: radial-gradient( center -9px, circle closest-side, white 0, red 26px );
background: -moz-radial-gradient( center -9px, circle closest-side, white 0, red 26px );
background: -ms-radial-gradient( center -9px, circle closest-side, white 0, red 26px );
background: -o-radial-gradient( center -9px, circle closest-side, white 0, red 26px );
background: -webkit-radial-gradient( center -9px, circle, white 0, red 26px );
background-color: red;
border: 2px solid white;
border-radius: 15px;
box-shadow: 1px 1px 2px black;
color: white;
font:15px Helvetica, Verdana, Tahoma;
font-weight:500;
padding-top:0px;
height: 14px;
line-height:16px;
padding-left:1px;
text-align: center;
width: 14px;
z-index:10;
}
<div class='alert-notify-circle notify-upper-left'>2</div>
Please let me know if you need more information, and thanks in advance for any and all help.
I believe this is a problem of font metrics. Using line-height to make the vertical alignment may give different results from browser to browser depending on how they render text. I would suggest to use padding to balance out vertical spacing, such as:
.alert-notify-circle {
min-width:.5em;
height:1.3em;
padding:0 .375em;
font:bold 1em Arial;
line-height:1.4em;
color: white;
border-radius: 1em;
border: 2px solid white;
box-shadow: 0 .25em .4em rgba(0,0,0,.33);
background-clip:padding-box;
background-color:#e91823;
background-image: linear-gradient(top, #F9BABD 0%, #ED3F48 50%, #E91822 50%, #C50104 100%);
background-image: -o-linear-gradient(top, #F9BABD 0%, #ED3F48 50%, #E91822 50%, #C50104 100%);
background-image: -ms-linear-gradient(top, #F9BABD 0%, #ED3F48 50%, #E91822 50%, #C50104 100%);
background-image: -moz-linear-gradient(top, #F9BABD 0%, #ED3F48 50%, #E91822 50%, #C50104 100%);
background-image: -webkit-linear-gradient(top, #F9BABD 0%, #ED3F48 50%, #E91822 50%, #C50104 100%);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #F9BABD), color-stop(0.5, #ED3F48), color-stop(0.5, #E91822), color-stop(1, #C50104));
}
Check out this badge I built for you as an example. I updated it for better cross-browser compatibility:
http://jsfiddle.net/x2xjB/3/
Recommended reading:
http://blog.typekit.com/2010/07/14/font-metrics-and-vertical-space-in-css/

Resources