I am using a js library (mermaid) to generate svg on a web page. I need to dynamically apply styling to parts of the svg as the user activates various commands using keyboard shortcuts, Particularly, I need to highlight the element in the svg that is currently designated as the selected one in the logical model. Looking at other questions on dynamically styling svg deal with inlined static svg, so they probably don't apply to my case and none of the methods I tried so far have worked.
The style I am trying to apply is
border-radius : 2rem; box-shadow : 0 0 3rem red;
when applied to regular html, this gives the element a glowing red border.
First thing I've tried was to include this as a class in a element in like this :
<style>
.highlight {
border-radius : 2rem;
box-shadow : 0 0 3rem red;
}
</style>
Adding the class to a regular html element 's class list like an , , or , would produce the desired styling. However when I would programmatically get a element and add the class to its class list, then it would remain without the glowing border. Inspecting the svg using chrome developer tools revealed that the relevant class has been added to the element's class list. Using the same method was successful for regular html. For reference here is the method I used to add the class:
graphicDiv.querySelector(selector).classList.add('highlight')
This having failed, I thought maybe the svg had some styling inside its internal element that overrode my styling, so I added !important to my styles so they would have highest precedence. This still failed to work, so next I tried to set the style property for the element, which should have the highest precedence like this:
graphicDiv.querySelector(selector).setAttribute('style', 'border-radius : 2rem !important; box-shadow : 0 0 3rem red !important;')
This still failed to produce any difference in the styling of the svg. Inspecting the element in chrome dev tools revealed the style attribute was indeed set.
I also tried adding my style definition to the svg's own element, by getting it after the svg is generated, and appending my class style definition to its text content. It would still not work.
Finally, I thought those css properties might not be supported by , so I changed them to background-color: green; instead, since I think I saw in an article on styling svg with css that this css prop was used on an . This didn't work. I tried applying to a element in the svg. Didn't work either.
I am completely baffled why none of this is working. I would massively appreciate if anyone could help me understand how I could dynamically change the styling of svg elements!
While normal CSS attributes can be given to SVG elements, most do nothing as SVG elements by definition adhere to a different set of styling rules.
A simple example is that in normal CSS you might set left: 25px but for SVG you would need to set x: 25.
For the styling you want, border radius is usually achieved with stroke-width. For background colour just use fill. As for a shadow, it may be a little more complex but you should have a look at feDropShadow.
Besides that, applying those styles with css rules should be roughly the same.
I hope that's at least some help.
Related
I have created a modal component in Angular. In a unit test, the modal is appearing in the DOM as shown:
However, I start out with a style on app-modal2 that includes display:none, so what actually renders is just the fixed text above the modal -- the content of the modal is correctly omitted:
When the user takes an action that adjusts the style to include display:block then the content of the modal correctly appears. Which is to say, the code is working exactly as I expect.
What I am confounded about is a unit test.
So: why my title ("Consternation on testing non-inherited-yet-inherited CSS display property") ?
Well, according to the docs, the display property is NOT inherited:
Using browser dev tools, I have confirmed that is true: descendant elements have values other than none for the display property. So even though descendant elements are affected by an ancestor having display: none it is because the subtree rooted at the ancestor is removed -- and this is not considered inheritance. Well, OK, potayto, potahto... Not technically inherited, but acts like it.
The visibility of my modal is controlled by the display property. It is set either to display: none or display:block depending on user actions. But that is strictly dealing with visibility, not existence. That is, #myContent is present with either display value. Since I therefore cannot test for existence of #myContent I must test strictly for visibility.
So how do I check an element for visibility controlled by some ancestor's display value, since display is not inherited? Is there a way to check for any ancestor having display:none? Or is there some other way to do this?
You can try using the jQuery parent() method, and put the style as the first argument.
I found out pretty disturbing your question. I think is one of the most hard questions to answer because goes right to the core of cascading and inheritance.
As far as I could find, display property is the only property that can't be specified (but computed) on how should be display by UA. HTML tags are pre-defined styles, those styles are display on UA without any CSS file, e.g. p elements are display as inline.
I tested it too with devtools; forgetting JS at all for very front-end purposes. (Maybe I'll check with with JS later as -second part-). This answer is intended for all audiences, newbies and experienced devs.
Before declare what is going to be styled, we may note that we have dependencies from the browser (User Agent) that parses the stylesheet.
We do not define all universe of properties to be styled, so when is not defined, a property needs to be set and the user agent roles to set a property (doesn't have to be its initial value), there's no official specification on how UA must render websites, it's expected them to be display as the stylesheet specifies, which often, does not act likely according browsing experience.
Cascading
One of the fundamental design principles of CSS is cascading.
What does an User Agent (UA) cascades? Elements? Properties? Objects?
Well, UA treat HTML tags as elements, and those elements are called as box tree, as the same, text included inside an element are called as text node.
Since CSS syntax and its parsing is a perfect cascade, that is the only word that remains if we need to figure out about how (UA) must display HTML documents. The UA also applies its own style sheet. This means that rendering also depends on the way (units) we use to specify values, if we specify a lot of different values e.g. pixels, cm, percentages, relative units (em, rem), etc, the more information UA needs to parse to be displayed, that's why front-end developers should be encouraged to perform clean css styles with homogeneous units to squeeze every milisecond out of browsing perfomance (such important in mobile experiences).
Inheritance
When no declarations try to set a the value for an element/property
combination. In this case, a value is be found by way of inheritance
or by looking at the property’s initial value.
What is called for inheritance, it's just the css properties that can be inherited (those are already established).
So, if a css property seems to be inherited, it's not really inheritance behavior, it's cascading behavior, and it's inheritance becomes by the nature of the syntax for the specified css property.
Answer
The display property is not inherited, but when none property is set, all the descendants elements will no generate any box-model subtree nor text node, (JS could be forcing the element to be display for testing purposes).
In the case of display:none; when the box tree and text node descendants are hidden by the parent element, the style applied of none is by cascading, not by inheritance.
In the example below, the span that is descendant of the fourth div element has set the background property as inherit, but the background can't be inherited, that's why the span element does not display any color background. Otherwise, the span that is descendant of the third div element inherits the color property. The fourth div element has display set: inline; once again, display can't be inherited, that's why the span element does not inherit that property and is displayed as block by the UA.
*{
border: 1px solid black;
}
.one {
display:block;
}
.two {
}
.three{
background:cornsilk;
}
.childthree{
color:red;
}
span{
background: inherit;
position: relative;
top:80px;
border: 5px solid black;
padding: 5px;
margin:5px;
}
.four{
display:inline;
}
canvas{
background:#99e6ff;
}
html {
padding:1em;
}
<div class="wrapper">
<div class="one">one</div>
<div class="two">two</div>
<div class="three">three
<div class="childthree">I'm a subtree inside the third div<br><span>I'm span tag</span></div>
</div>
<div class="four">four<p>i'm a p tag with thext content<span>I'm a span element inside a p element</span></p</p>
<canvas></canvas>
</div>
What is the best practice for creating specific page breaks in SAPUI5 and is it actually possible?
Classical CSS atributes page-break-after and page-break-beforedoesn't seem to work in my case. For example, I have two sap.m.VBox elements and I attached them a CSS class which specifies page-break-after: always !important;when printing, but nothing happens. If I add
* {overflow-x: visible !important; overflow-y: visible !important;} then it will break and continue to draw the content in next page if it doesn't fit in one page, but it doesn't work in IE.
I have tryed also adding an empty div element that would work as a page break indicator, but still CSS wouldn't do anything. I guess that's because everything in SAPUI5 is put into one content div.
You can solve this by adding an empty element in between.
If you want a break that is 200 pixels high, your page content can look like this:
return new sap.m.Page({
content:[
oVBox1,
sap.m.Panel({height: "200px", width: "100%}),
oVBox2
]
});
ofcourse you might want to set your panel background-color to transparent ;)
The "page-break-after" is ignored because the property display of SAPUI5 views is set to inline-block.
Simply override the CSS style for the corresponding class with a custom CSS and it should work:
.sapUiView {
display: block;
}
I have an ul with a background-color of rgba(15,15,15,0.8). I want a li element of the list to be more transparent, e.g. I want it to have background-color set to rgba(15,15,15,0.5). The problem is that being the inner li element transparent, I see the background color of its ul parentso what I get is actually an even darker background
Is there a way in CSS (but for that matter it would be fine through JS/jQuery too) to "cancel" the background property of the parent?
Edit
Note that also colouring the "rest" of the list (the part of the list not made by lis) would be fine, even if I don't think it's easy nor a good solution.
You could do it by not setting a background on the ul and setting RGBa borders on the li.
demo
Relevant CSS:
border: solid .5em rgba(15,15,15,.8);
background: rgba(15,15,15,.5);
(you can adjust the width values of the borders to suit your needs)
if you're just trying to lighten the colour (as opposed to letting underlying images or text show through), you might consider using background-color: rgba(256,256,256,0.3) which would put a light haze of white over your child element.
view here: http://jsfiddle.net/9VBnr/
You might also check out this oldie but goodie from Eric Meyer: http://meyerweb.com/eric/css/edge/complexspiral/demo.html
Sorry, but that would be like expecting a clearer view by putting a shaded piece of glass on top of another piece of shaded glass. It would just not work. :)
What you need to do is to reverse the way you think. Make the topmost layer have the right look and then move to the one beneath it.
Style the li elements with a none transparent background. Use a sprite to get the look you want if you need something else but pure color. Then move on to the ul element and give that the look you want - even using opacity.
I have a button that can have a focus css class associated with it and I instantiate this at runtime within Javascript.
This is all provided by a bespoke Javascript framework so can not be changed.
Normally I would provided 2 additional CSS class for this button,
e.g.
btn { background-image: url(/btn.png);}
btn.focus { background-image: url(/btn-focus.png);}
This will give me 2 different images based on whether the button is 'focused' or not.
The problem I have now is that the image urls are dynamically loaded at runtime, and there is no way of specifying them with a static CSS file.
I'm thinking one possible solution is to 'somehow' generate a new style element with the btn and btn.focus classes in it (with the dynamic URLs) and either append it to the head or embedded it in the markup prior to instantation of the Button itself. This solutions doesn't seem ideal.
Can anyone suggest anything else?
Thanks in advance.
If your case is specifically about images that represent different states of a single object (e.g. focused or non-focused state of a button) then it's a good idea to use sprites.
That is creating a single image with all button states and loading it (dynamically if you want).
Then you can write a universal rule in your CSS:
btn {background-position: 0 0;}
btn.focus {background-position: 0 -20px;} /* 20px is the height of your button*/
Are you saying this doesn't work because their css styles "inline" ones are overriding your ones? If so then do this instead
btn { background-image: url(/btn.png) !important;}
btn.focus { background-image: url(/btn-focus.png) !important;}
Lately I wondered about editing elements styles not by switching their classes on dom, but by changing the actual ruleset for the css class or selector.
So instead of something like
$('.some').hide()
or
$('.some').addClass('hidden')
Why not alter a rule directly with document.styleSheets and stuff?
Wouldn't this approach be generally more performant, at least with many elements, as we'd let the browser handle the ruleset changes natively?
You could for example add an style to .some, like display: none; and all .some elements would be immedeatly be hidden. There is no need to iterate over all those elements in js and hide them manually(like the example above).
Changing rulesets directly would more likely encourage classes that are context aware(or however you would call this..), as you'd hide all #persons > .item or something.
I still don't know best practices regarding classes that are named with context in mind, like for example control names like .calendar .ticket .item, versus single functionality classes like .hidden .left .green, as I usually need both types of conventions.
I am just asking what you think about this and what are benefits and drawbacks of the modifiying stylesheet approach versus how libraries like jquery handle changing styles?
Also, what do you think is good practice, what do you regard more as a hack?
cough javascript and hacking cough
Manipulating document.styleSheets is tricky due to differing implementations and the lack of a rule selector API. Currently if you want to manipulate a rule in a stylesheet you have to go through this process:
iterate over document.styleSheets
iterate over rules within current styleSheet object
if rule matches our class, edit the rule styles
Then there's the cascading issue. How do you know that a particular style on the rule you've matched won't be overridden by a different rule somewhere in the pages stylesheets? If you just bail out after changing the first matching rule you find, you can't be sure that the styles you set will actually be applied to the element, unless you stick an !important on each one, which will leave you with a whole different set of problems.
Even when you've manipulated the style sheet rules, the browser still has the same job to do — it has to recalculate all the styles by applying the cascade.
So, manipulating styleSheets doesn't look too appealing now, does it? Stick to class switching, trust me. Using jQuery and modern APIs like querySelectorAll make it plenty fast and the browser still does all the hard work like recomputing the style values.
Such a tricky question :(
But if you take boilerplate for instance, it has a some standard classes to use like:
/* Hide from both screenreaders and browsers: h5bp.com/u */
.hidden { display: none !important; visibility: hidden; }
/* Hide only visually, but have it available for screenreaders: h5bp.com/v */
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: ; position: absolute; width: 1px; }
/* Hide visually and from screenreaders, but maintain layout */
.invisible { visibility: hidden; }
Where it gets tricky is, IF it is something you need to hide because of JS, then you should ONLY hide it with JS. Then it will function if JS is disabled.
If it is something that is not JS dependent, then you hide it in the HTML.
So JS function = hide with JS (either by using JS or adding hide classes)
Basic HTML hide = hide with HTML class
Styleswitching vs JS switching
Basicly JS switching gives you the oppertunity to add effect etc, just using predefined classes limits that somewhat. But would love to see some ressource comparisons :)