CSS not overriding presentational SVG attributes - css

I have an SVG shape as part of my SVG sprite:
<symbol id="flickr-logo" viewBox="-41.5 532.5 200 91.626">
<circle fill="#0063DB" cx="4.313" cy="578.312" r="45.813" class="left" ></circle>
<circle fill="#FF0084" cx="112.687" cy="578.312" r="45.813" class="right"></circle>
</symbol>
Now when I use <svg ..><use ...></use></svg> etc to include the actual shape on my page it works nicely and the fills inside the SVG circles show up fine.
Now, when I add my css from below:
.left {
fill: #ffffff;
}
.right {
fill: #ffffff;
}
Nothing happens. I see the style is applying but the fill="???" presentational attribute on on the circle elements seem to be overriding. Is there a way to get the CSS to win out?
If I remove the fill="????" attribute then the css styles work perfectly but I need to keep them in.
I thought about editing the colours in the SVG but I can't as I need to display this shape in two locations. One in it's default colours and once in another place where I need to change the fills to white.
Any thoughts about how to do this?
Thanks,
Neil

I would suggest that you remove the fill then CSS can be applied and work as expected.
You say you can't do this as you use the SVG in two places.
However your mark-up shows
<symbol id="flickr-logo" viewBox="-41.5 532.5 200 91.626">
So I guess that, you must be using another ID somewhere else (or you could use another ID somewhere else) such as id="flickr-logo-alt" as all the ID's on the page actually really need to unique.
You can then apply two little bits CSS to style both versions.
#flickr-logo .left {
fill: #0063DB;
}
#flickr-logo .right {
fill: #FF0084;
}
#flickr-logo-alt .left {
fill: #ffffff;
}
#flickr-logo-alt .right {
fill: #ffffff;
}
If you have other styling that references the ID and you don't have two on the page at the same time, then you could add a class to the symbol for the alternate case "alt" use different classes like this. The class can be applied directly or through scripting.
<symbol class="alt" id="flickr-logo" viewBox="-41.5 532.5 200 91.626">
#flickr-logo .left {
fill: #0063DB;
}
#flickr-logo .right {
fill: #FF0084;
}
#flickr-logo.alt .left {
fill: #ffffff;
}
#flickr-logo.alt .right {
fill: #ffffff;
}
or just apply an additional class to the left and right that already exist in the alt case. Which can be applied directly or though scripting.
<circle cx="4.313" cy="578.312" r="45.813" class="left alt" ></circle>
<circle cx="112.687" cy="578.312" r="45.813" class="right alt"></circle>
.left {
fill: #0063DB;
}
.right {
fill: #FF0084;
}
.left.alt {
fill: #ffffff;
}
.right.alt {
fill: #ffffff;
}

Related

How to control SVG filter attribute values using CSS?

I want to create animation in CSS, part of which I need to control the values of the SVG filter attributes.
Below, I try to call a CSS variable within the specularConstant attribute, and the browser returns an error.
Alternatively, is it possible to set the attribute using a selector in the CSS code, or is there any way to control an SVG attribute like this, via CSS?
Below a Reproducible Example:
#property --illumination-power {
syntax: '<number>';
initial-value: 1;
inherits: true
}
:root {
animation: my-animation 5s;
}
#keyframes my-animation {
0% {
--illumination-power: 0;
}
100% {
--illumination-power: 1.2;
}
}
body {
margin: 0;
background-color: black;
}
<svg width="100vw" height="100vh">
<defs>
<filter id="spotlight">
<feSpecularLighting specularConstant="var(--illumination-power)"
specularExponent="10" lighting-color="white">
<fePointLight x="200" y="100" z="70"/>
</feSpecularLighting>
</filter>
</defs>
<rect id="light-background" x="-500%" y="-500%" width="1000%" height="1000%" fill-opacity="0" filter="url(#spotlight)"/>
</svg>
You need to use the SVG <animate> element or JavaScript to do it.

CSS SVG Wave shape

that's the result I'm trying to achieve
and here's what I've done: https://codepen.io/demedos/pen/gjQNOM
HTML structure:
.container
.header
.page-1
#wave
#dot
#text
There is some problem though:
Items are positioned using absolute positioning, while I want them anchored to the main wavy line
Containers are smaller than their content
I want the line to be at 50% of the screen, filling the above space with its background color
Here's a solution using a little bit of Javascript. I've simplified your example to keep things clear.
I want the line to be at 50% of the screen, filling the above space with its background color
We use a vertical flex box arrangement to fill the height of the screen.
We set the viewBox to fit the wave curve and let the browser do normal SVG centering.
We use a very tall wave path and rely on SVG overflowing to make the wave fill to the top of the cell.
We use SVGPathElement.getPointAtLength() to calculate the correct position on the path for each dot.
function positionDot(dotId, fractionAlongWave) {
// Get a reference to the "wave-curve" path.
var waveCurve = document.getElementById("wave-curve");
// Get the length of that path
var curveLength = waveCurve.getTotalLength();
// Get the position of a point that is "fractionAlongWave" along that path
var pointOnCurve = waveCurve.getPointAtLength(curveLength * fractionAlongWave);
// Update the dot position
var dot = document.getElementById(dotId);
dot.setAttribute("cx", pointOnCurve.x);
dot.setAttribute("cy", pointOnCurve.y);
}
// Position the first dot 25% the way along the curve
positionDot("dot1", 0.25);
// Position the second dot 90% of the way along the curve
positionDot("dot2", 0.90);
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
.container {
display: flex;
flex-direction: column;
width: 640px;
height: 100vh;
margin: 0 auto;
border: 1px solid blue;
}
.header {
background-color: #333835;
}
.page-1 {
flex: 1;
border: 1px solid red;
position: relative;
}
.page-1 svg {
position: absolute;
width: 100%;
height: 100%;
border: 1px solid red;
}
#wave {
fill:#333835;
}
#dot1,
#dot2 {
fill:#e05a5a;
}
<div class='container'>
<div class='header'>
header
</div>
<div class='page-1'>
<!-- Set the viewBox to match the curve part of the wave.
Then we can rely on the browser to centre the SVG (and thus the curve) in the parent container. -->
<svg viewBox="0 342 1366 283">
<defs>
<!-- A copy of the curve part of the wave, which we will use to calculate
the correct position of the dot using getPointAtLength(). -->
<path id="wave-curve" d="M0,342c595,0,813,283,1366,283"/>
</defs>
<!-- SVGs are "overflow: visible" by default.
If we make this path extend vertically a long way, it will fill to the
top of the SVG no matter how high the page is. -->
<path id="wave" d="M0,342c595,0,813,283,1366,283 V -10000 H 0 Z"/>
<circle id="dot1" cx="0" cy="0" r="12.5"/>
<circle id="dot2" cx="0" cy="0" r="12.5"/>
</svg>
</div>
</div>

CSS blur only in one direction (motion blur)

I need to dynamically blur an image on my page, but only along one axis (Y specifically). So here are my requirements:
Has to be done "live" (I can't pre-render a blurred version of the image)
Like I said, only on the Y axis (like a motion blur, but vertical)
Needs to animate in
Should work in IE9+
My first thought was to use a simple CSS filter:
img {
filter: blur(20px);
}
I can animate that by adding a transition (transition: filter 0.2s linear), but it only creates Gaussian blurs, which isn't the effect I want. The syntax doesn't support something like filter: blur(0 10px); to restrict the blur only to one axis.
Then I read that the blur filter (amongst others) is really just a shorthand for an SVG filter, which you can write manually if you want. So I created an SVG called filter.svg that specifies a 20px blur only along the Y axis (0 20):
<?xml version="1.0" standalone="no"?>
<svg width="1" height="1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="0 20" />
</filter>
</defs>
</svg>
And applied it like this:
img {
filter: url("filter.svg#blur");
}
And that works perfectly...but only in Firefox. Safari/Chrome don't support url() as a value for filter. Plus, I can't animate it because the value is a URL rather than a number, so transition doesn't work.
On top of all that, I don't think either of these approaches work in IE9.
So: is there any way to do what I'm trying to do? I've looked into using canvas as an alternative, but can't find any examples of a blur that only goes in one direction.
If I'm understanding the question right it can be donewith JQuery.
CSS3 does have it's limits and it's very limited in interactive values.
Jquery also adds cross-platform stability.
JQuery
$(document).ready(function() {
var $img = $('.image')
$img.hide();
$img.show().animate({
opacity: 100,
paddingTop: '+=80'
}, 500)
});
Here is an example of how it could work with javacript with a little
fooling around on opacity.
function myMove() {
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos == 150) {
clearInterval(id);
} else {
pos++;
elem.style.left = pos + 'px';
}
}
}
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id="container">
<div id="animate"></div>
</div>

change image sprite on click for button using CSS

change button image onclick then return to original image after click
<style>
img.button-send {
background: url(img/agentsprite.png) 0 0;
width:87px;
height:34px;
opacity:0;
}
img.button-send:active {
background: url(img/agentsprite.png) 34 174;
width:87px;
height:34px;
}
</style>
<button type="submit">
<img class="button-send" src="img/img_trans.gif" width="1" height="1" />
</button>
i'm using a sprite for this, and it seems that it won't go to that image position when i click it, is there any way for this to work ? i wan't to have a button effect for this field when pressed.
...........................
hi now used to px value in your background-position image
as like this
img.button-send:active {
background: url(img/agentsprite.png) 34px 174px;
}
or you can used this also
img.button-send:active {
background-position:34px 174px;
}
px value according to your design

Firefox Sprite Sheet Image Not Showing Up

I'm trying to create a chat room with emoticons. When a user types an emoticon such as :) in the chatroom, the CSS takes the proper image off the sprite sheet. But my code only seems to work in Opera and IE (odd combination). It doesn't show in Firefox or Chrome (if you manage to hone in exactly where the image should be, you can find the image blank.gif which is used as the stand-in to place the background-url over). Does anyone know what might cause this in Firefox/Chrome?
Site: ttony21.byethost24.com
Relevant CSS:
image.emo {
width:19px;
height:19px;
}
image#smile {
background:url(img/diceSprite.png) 0 0;
}
image#bigsmile {
background:url(img/diceSprite.png) -19px 0;
}
etc...
Relevant HTML:
<img class="emo" id = "smile" src="img/blank.gif" width="1" height="1" alt=":)" title=":)" />
<img class="emo" id = "bigsmile" src="img/blank.gif" width="1" height="1" alt=":D" title=":D" />
etc...
change
image.emo {
width:19px;
height:19px;
}
to
img.emo {
width:19px;
height:19px;
}
and the others follow a similar pattern. The element selector is img, not image

Resources