Coloring SVG content url with css - html

I have a button set up like this:
<button class="buttonclass"><i class="iconclass plus-icon"></i></button>
My css classes look like this:
.buttonclass {
width: 30px;
height: 30px;
text-align: center;
position: relative;
border-radius: 20px;
background-color: #1DBE60
}
.iconclass {
width: 20px;
height: 20px;
margin: 7.5px;
}
.buttonclass .iconclass {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.plus-icon {
content: url(http://uxrepo.com/static/icon-sets/mfg-labs/svg/plus.svg);
}
How can I change the color of the 'plus-icon' with css if it is an SVG? I have tried adding fill classes to the svg, color classes, background-classes, etc.
Here is a plunk:
http://plnkr.co/edit/6fLYQlpFmDdf7aWenBtp?p=preview

If you're happy to add one extra class (for the color of the plus icon) then here's a CSS-only solution using the currentColor CSS variable:
.buttonclass {
width: 30px;
height: 30px;
text-align: center;
position: relative;
border-radius: 20px;
background-color: #1DBE60
}
.iconclass {
width: 20px;
height: 20px;
margin: 7.5px;
}
.buttonclass .iconclass {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.plus-icon {
background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><rect x="0" y="0" width="8" height="8" fill="rgb(29,190,96)" /><rect x="0" y="12" width="8" height="8" fill="rgb(29,190,96)" /><rect x="12" y="0" width="8" height="8" fill="rgb(29,190,96)" /><rect x="12" y="12" width="8" height="8" fill="rgb(29,190,96)" /></svg>');
background-color: currentColor;
border: 1px solid rgb(29,190,96);
border-radius: 15px;
}
.white {
color: rgb(255,255,255);
}
.yellow {
color: rgb(255,255,0);
}
.green {
color: rgb(0,255,0);
}
<button class="buttonclass"><i class="iconclass plus-icon white"></i></button>
<button class="buttonclass"><i class="iconclass plus-icon yellow"></i></button>
<button class="buttonclass"><i class="iconclass plus-icon green"></i></button>

You have to put the svg inline but consider using the <use> element instead so you can use an icon multiple time by referencing it:
http://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css/

I ended up here looking for a way to color a svg icon. The most voted answer didn't helped me so after some googling i came across to this interesting codepen.
Long story short i colored my svg icon using this css:
.plus-icon {
-webkit-mask: url('../images/plus.svg') no-repeat 50% 50%;
mask: url('../images/plus.svg') no-repeat 50% 50%;
-webkit-mask-size: cover;
mask-size: cover;
}
.white {
background-color: rgb(255,255,255);
}
Update:
Not working with IE.

Related

How to outline only visible part of an element?

I'm trying to improve my css skills, and wanted to draw like a moon and outline it. I mad this by using 2 circles and the second one has the same color as the background so it look like a moon. However now i want to outline/ give it a border but i don't know how to do this, because the other parts are overlapped with the secon circle.
body{
position: relative;
background-color: white;
padding-left: 40%;
}
#div1{
position: absolute;
height: 400px;
width: 400px;
border-radius: 100%;
background-image: linear-gradient(45deg, #050182, #51bfdb);
border: 3px solid black;
}
#div2{
position: absolute;
height: 350px;
width: 350px;
background-color: white;
border-radius: 50%;
margin-left: 110px;
margin-top: 25px;
z-index: 2;
}
<div class="container">
<div id="div1"></div>
<div id="div2"></div>
</div>
I would simplify your code using mask then I will rely on drop-shadow filter for the outline
#div1{
filter:drop-shadow(0 0 1px #000) drop-shadow(0 0 0 #000) drop-shadow(0 0 0 #000);
}
#div1:before {
content:"";
display:block;
height: 200px;
width: 200px;
border-radius: 50%;
background-image: linear-gradient(45deg, #050182, #51bfdb);
-webkit-mask: radial-gradient(circle 100px at 80% 50%,#0000 98%,#000);
}
<div id="div1"></div>
You can add border left property to div2 for desired result.
body{
position: relative;
background-color: white;
padding-left: 40%;
}
#div1{
position: absolute;
height: 400px;
width: 400px;
border-radius: 100%;
background-image: linear-gradient(45deg, #050182, #51bfdb);
border: 3px solid black;
}
#div2{
position: absolute;
height: 350px;
width: 350px;
background-color: white;
border-radius: 50%;
margin-left: 110px;
margin-top: 25px;
z-index: 2;
border-left: 3px solid black;
}
<div class="container">
<div id="div1"></div>
<div id="div2"></div>
</div>
Like Justinas already commented, you're kind of trying to do SVG's job in CSS here, which is pretty clunky and inefficient.
If you know a little HTML and CSS, which it seems you do, then SVG will feel like just more of the same.
SVG will just look like a couple new HTML elements to you, and you just sprinkle it right into your HTML; It also just uses the same CSS stylesheet that as your HTML already uses.
To illustrate, run this snippet here; just a couple lines of CSS and some SVG, i'm sure you can tell what 90% of it means instantly.
body { background-color: #FFF; }
svg { background-color: #CCC; }
.gradient_start { stop-color:rgb(255, 255, 0); stop-opacity: 1; }
.gradient_end { stop-color:rgb(255, 0, 0); stop-opacity: 1; }
text { font-family: "Verdana"; font-size: 32pt; }
<html>
<body>
<svg width="400" height="200">
<defs>
<linearGradient id="mygradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" class="gradient_start" />
<stop offset="100%" class="gradient_end" />
</linearGradient>
</defs>
<ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#mygradient)" />
<text x="150" y="86" fill="#ffffff">
Turtles !
</text>
</svg>
</body>
</html>
In SVG you have access to a lot more drawing elements, such as the <ellipse> used in this example.
Look at the result, using the border-left property.
body{
position: relative;
background-color: white;
padding-left: 40%;
}
#div1{
position: absolute;
height: 400px;
width: 400px;
border-radius: 100%;
background-image: linear-gradient(45deg, #050182, #51bfdb);
border: 3px solid black;
}
#div2{
position: absolute;
height: 350px;
width: 350px;
background-color: white;
border-radius: 50%;
margin-left: 110px;
margin-top: 25px;
z-index: 2;
border-left: 2px solid black;
}
<div class="container">
<div id="div1"></div>
<div id="div2"></div>
</div>

ViewBox issue for SVG responsive button

I'm creating a button with rounded corners using SVG (I have to use SVG).
So I succeed to make it responsive related to his parent element #btnTour which I put a width and a height on. But I always have a gap between this #btnTour and the path of my SVG I think it's related to the viewbox but after reading bunch of articles about it I still can't figured out how to solve my issue.
Thanks for your help.
#btnTour{
display: inline-block;
background: none;
border: none;
outline: none;
position: relative;
margin: 1em;
padding: 0;
width: 192px;
height: 70px;
text-decoration: none;
}
#svgContainer{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 100;
border: dotted 1px red;
}
#btnTourText{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
margin: 0;
text-align: center;
z-index: 100;
font-size: 25px;
color: #2b5e9d;
font-weight: 600;
white-space: nowrap;
}
<a id="btnTour" href="page2.php">
<div id="svgContainer">
<svg width="100%" height="100%" viewBox="0 0 300 125" preserveAspectRatio="none">
<path id="svgBtn" style="fill:none;stroke:#2b5e9d;stroke-width:2;" d="M286.5,62.5C286.5,90.39099999999999,263.891,113,236,113C236,113,171.64499999999998,113,150,113C128.355,113,64,113,64,113C36.109,113,13.5,90.39099999999999,13.5,62.5C13.5,62.5,13.5,62.5,13.5,62.5C13.5,34.609,36.109,12,64,12C64,12,128.35500000000002,12,150,12C171.645,12,236,12,236,12C263.891,12,286.5,34.609,286.5,62.5C286.5,62.5,286.5,62.5,286.5,62.5C286.5,62.5,286.5,62.5,286.5,62.5"></path>
</svg>
</div>
<p id="btnTourText">Go on a Tour</p>
</a>
yes, you have to set the view box to fit the path ( eg. something like viewBox="12.5 11 275 103"); you can do it programmatically via js ( compute the bounding box to the to be fit svg element ) or set/get it from your preferred svg authoring app...

Make HTML/CSS responsive

Due to the skills of others in the community I have created this:
http://codepen.io/anon/pen/NbdoKV
HTML:
.clipboard:after, .clip, .clip:before, .paper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.clipboard {
position: relative;
display: block;
height: 27em;
width: 23em;
margin: 5em auto;
border-radius: 3%;
background: #b69b4c;
}
.clipboard:after {
top: 2.25em;
content: "";
height: 1.5em;
width: 20em;
background: #fefefe;
}
.clip {
z-index: 2;
top: 4.2em;
display: block;
height: 10em;
width: 17em;
border-radius: 50%;
background: #A7A7A7;
}
.clip:before {
content: "";
top: -.5em;
height: 5.3em;
width: 5.3em;
border: 2.2em solid #A7A7A7;
border-radius: 50%;
}
.paper {
z-index: 2;
display: block;
height: 23em;
width: 20em;
margin-top: .5em;
background: #fefefe;
}
.paper:before {
content: "";
position: absolute;
bottom: 0;
right: 0;
height: 3.25em;
width: 3.25em;
}
.paper:after {
content: "";
position: absolute;
height: 1.25em;
width: 1.5em;
}
<i class="clipboard">
<i class="clip"></i>
<i class="paper"></i>
</i>
As you can see this graphic does not scale / respond very well. If I set the width to 100%, everything loses its ratio / perspective. Ideally, I want to be able to set the clipboard width to 100% and everything (height, the clip at top, padding etc) will then scale correctly - much like an image would.
I can see 2 ways of making this responsive:
Changing the HTML/CSS - I have tried and failed
Converting this HTML/CSS to SVG - no idea where to start
How would you make this responsive?
This is an example as svg. There are a few sites where you can draw svgs.
Then you have the paths.
I think the different attributes are self explaining. If you have any questions ask please. I think the best is to read more about this if you want to use it.
Maybe here but there are many more good sources.
<svg height="200" width="450">
<path
id="lineAB"
fill="khaki"
d="M9.778,96h108.445c5.400000000000006,0,9.778000000000006,-4.378,
9.778000000000006,-9.778000000000006v-68.445c0,-5.4,-4.378,-9.778,
-9.778000000000006,-9.778h-108.445c-5.4,0,-9.778,4.378,-9.778,
9.778v68.445c0,5.400000000000006,4.378,9.778000000000006,
9.778,9.778000000000006ZM8,16h112v72h-112v-72Z"
transform="matrix(0.000503985 -1.04456 1.29502 0.000406514 -10.7973 124.73)
translate(-60,150)" />
<path
fill="#C0C0C0"
d="M109.58289641986332,32.006086609509h8v-6.222000000000001c0,-5.3999999999999995,
-4.378,-9.778,-9.778000000000006,-9.778h-30.221999999999994v-6.2219999999999995c0,
-5.4,-4.378,-9.778,-9.778000000000006,-9.778h-20.445c-5.3999999999999995,0,
-9.777999999999999,4.378,-9.777999999999999,9.778v6.222000000000001h-30.222c-5.3999999999999995,
0,-9.778,4.378,-9.778,9.777999999999999v6.222000000000001h112ZM45.58289641986323,
8.006086609509033h24v8h-24v-8Z"
transform="matrix(0.560377 0.00141111 -0.00141111 0.560377 25.8245 -9.95107)
translate(340,90)"/>
Now you only need to adjust the height and with
respectively adding a scale at the transform attribute.

How to transform block in css?

How to transform block in CSS? Pseudo-elements is need or not? I try to create block look like block on the picture below. I can't create such block as on the picture below.
This is my code:
.transform_items {
width: 40%;
height: 80px;
position: relative;
margin: 0 auto;
perspective: 600px;
margin-top: 150px;
left: 50px;
}
.block,
.block::before{
display: block;
position: absolute;
margin: 0 auto;
}
.block {
border: 5px solid transparent;
width: 350px;
height: 60px;
}
.block::before {
content: '';
border: 5px solid #52B352;
transform: rotateY(30deg);
top: -5px;
right: -5px;
bottom: -5px;
left: -35px;
}
.block a {
font-size: 24px;
}
<div class="transform_items">
<div class="block"><a>Block</a></div>
</div>
The expected result:
If you can use SVG (1), it could be like this
codePen
svg #block {
stroke: orange;
fill: none;
stroke-width: 5
}
svg text {
font-size: 25px
}
<svg version="1.1" x="0px" y="0px" width="274px" height="84px" viewBox="0 0 274 84">
<polygon id="block" points="33,13 245,24 245,60 29,64 " />
<text x="100" y="50">BLOCK</text>
</svg>
You can also save the svg code as a .svg file,without the text element, and use it as background-image for the div that contains your text
Read this to learn how to use svg in different ways: https://css-tricks.com/using-svg/
(1) Browser support for SVG is a little better than browser support for transform, caniuse: SVG

background-color ignores transparent content?

I have the image which has filled content and transparent content. I want to get background-color but only for filled content (ignores transparent) Is it possible? Can I do something like that instead?
My project: can be seen here
$("#hairbutton").click(function() {
var haircolor = $('#haircolorinput').val();
$(".img-wrap#hair img").css("background-color", haircolor);
});
$("#facebutton").click(function() {
var facecolor = $('#facecolorinput').val();
$(".img-wrap#face img").css("background-color", facecolor);
});
#-webkit-keyframes head {
from {
top: 0px;
}
to {
top: 1px;
}
}
#keyframes head {
from {
top: 0px;
}
to {
top: 1px;
}
}
#head {
position: relative;
-webkit-animation: head 1.5s infinite;
animation: head 1.5s infinite;
}
.img-wrap {
width: 153px;
height: 78px;
overflow: hidden;
width: 90px;
height: 60px;
clear: both;
}
.img-wrap img {
width: 90px;
height: 60px;
background-color: green;
}
input {
padding: 5px;
border-radius: 5px;
border: 2px solid black;
float: left;
height: 18px;
}
input:focus {
outline: 0;
}
#go {
padding: 5px;
border: 2px solid black;
width: auto;
display: table;
border-radius: 5px;
float: left;
height: 10px;
margin-left: 5px;
cursor: pointer;
height: 33px;
}
#face {
position: relative;
bottom: 35px;
left: 35px;
}
.form {
float: left;
clear: both;
}
button {
position: relative;
left: 5px;
top: 5px;
}
.clear {
clear: both;
}
<div class="form">
<input id="haircolorinput" name="haircolor" type="text" placeholder="Hair HEX">
<button id="hairbutton">Change</button>
</div>
<div class="form">
<input style="margin-top: 5px; margin-bottom: 50px;" id="facecolorinput" name="facecolor" type="text" placeholder="Face HEX">
<button id="facebutton">Change</button>
</div>
<div class="clear"></div>
<div id="head">
<div class="img-wrap" id="hair" style="z-index: -100;">
<img src="http://i.imgur.com/mz3GRLl.png" alt="" />
</div>
<div class="img-wrap" id="face" style="z-index: 100; width: 36px; height: 36px;">
<img src="http://i.imgur.com/DiHXscR.png" alt="" style="width: 36px; height: 36px;" />
</div>
</div>
To answer your question No, but you can sett a background-color to and image so that the background shows on the transparent part of you image instead:
tl;dr There are multiple ways of changing parts of an image/object. I think the easiest way is with an svg embedded image/object. and setting the fill of that element with css.
Fidely dee
PNG example
CSS
#yourimage:hover {
background-color: blue;
}
The setback of using the png solution:
This will fill any background color. So to avoid having blue background around an image usually you have a white or any other solid background on the image. See fiddle for example.
Canvas
Its fully possible setting the the strokeStyle in canvas.
Yay super easy right? Well canvas does not have objects or elements it only renders what is given to it. So in the code that draws you shape you have to define what color it takes before rendering. Maybe one day there will be elements in canvas?
SvgRecommended
Svg elements can have an id! So we can simply make an svg:
html
<svg width="100" height="100">
<circle id="favcirc" cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow"/>
<svg/>
And access the fill value of the element!
css
#favcirc {
fill = "#F00"
}
ps if you lucky and only have one color you can hue-rotate it with filter:
Filter demo