SVG: Use Attributes or CSS to style? - coding-style

In HTML it is recommended to seperate Content from Style, thus you should create external CSS-Files for your styles. As I am just getting started with SVG I now wonder: Does this rule also apply for SVG?
What is considered better code style?
<circle fill="yellow" />
or <circle style="fill: yellow;" />

I arrived here because I was trying to remember whether attributes or styles have greater precedence. This is one practical reason why you'd want one over another.
Attributes get applied as "presentation hints", as if they were the first of the cascading style sheets. In other words, this gives them lowest precedence.
Thus the precedence, from lowest to highest, is
attributes
CSS style sheets
inline styles
It's a little confusing that an inline style has much greater precedence than the attribute it's next to. (I keep having to look this up!)
There aren't going to be any new presentation attributes, and we are encouraged to use CSS styling instead, but it doesn't sound like presentation attributes are going away anytime soon.
More detail can be found in the Presentation Attributes section of the Styling chapter of the SVG standard.

I would generally prefer <circle fill="yellow" /> to <circle style="fill: yellow;" /> because it's shorter and easily to manipulate with, for example, getAttributeNS(null, "fill").
But over that I would prefer using a separate style element, just as with HTML, e.g:
<style>
circle{
fill: yellow;
}
</style>
Which has all the same advantages of using CSS, such as making it easy to change the stlye of lots of elements at once.
You can also put your CSS in an external file and add:
<?xml-stylesheet type="text/css" href="your_CSS.css" ?>
Before the svg element.

I have found Presentation Attributes vs Inline Styles on css-trick really useful for this.
From it:

The difference is always if it's content or it's presentation.
If the circle is content and it has to show whether or not there css available, then the first option is the one.
But if the circle is just part of the site disign and doesn't add anything to the content, then it should be the second option. Or use a css class.

Related

AdminLTE themes: small disagreement with coworker (soft skills)

I have a quick question regarding implementation of a small change in our system, and I want to hear your opinion about my little disagreement with another developer in our company.
Our working environment:
Laravel
AdminLTE
Two laravel guards for 'partner' and 'staff'. Each type of user (partner/staff) has access to a different set of pages, using a different set of controllers and a different subdomain.
Admin LTE comes with some skins that you can apply to your <body>, for example 'skin-blue' theme. This is what our page looks like. Just for a comparison, if you remove the 'skin-blue' class, our website looks like this.
We were asked by our client to change the color of the top navbar for the Staff side. So, because the colors at the moment are being added by an adminLTE skin, I thought it was better to create a second theme for the staff side, calling it "skin-staff", and then in our base blade file, check for which guard is being used, and add the class accordingly.
<body class="#if(get_guard() === 'partner') skin-blue #else skin-staff #endif" ...>
I made a copy of the original skin-blue file, renamed it to skin-staff, and just changed the color of the necessary elements. I thought this was the best way to go about it, but the developer which had to review my github Pull Request said that because this was such a small change, it wasn't necessary to create a new skin. His proposed solution was to simply add the css classes in the blade file, something like:
<head>
…
<style type="text/css">
#if (get_guard() === 'staff')
.skin-blue .main-header .navbar{
background-color:#bdac3c
}
.skin-blue .main-header .navbar .sidebar-toggle:hover{
background-color:#ac9b2b
}
.skin-blue .main-header .logo{
background-color:#bdac3c;
}
… // and other classes
#endif
</style>
Now, to me this is not correct, because we are mixing the logic for staff and partner side without a clear way to differentiate them. If we use skins, we can simply say something like "The top navbar is yellow because we are using class skin-staff". And "We are using class skin-staff because we are on the Staff guard". The propositions are clear and simple. However, by adding raw CSS to our blade file, we end up with something like "The top navbar is yellow because we are using skin-blue and also we are on the Staff guard and also we have added some custom CSS for the Staff guard". The extra changes we introduce to the system don't follow the pattern used by adminLTE, to me they just look like noise. If we had to for example do this five more times, we would end up with a lot of CSS in our base blade file, which I think would look bad and would force us to eventually decide to use the skin system of adminLTE, something we could just do right away.
But, being as stubborn as I know I am, I don't know if I have the right idea or if I just want to do things my way.
What do you guys think? Is it better to create a new skin, even if most of the CSS code inside the skin file will be duplicated, but it allows us to stick to the existing way of doing things, or is it better to just add the code in the blade file and don't think more about it?
Thanks for your ideas
This is very much an opinion based question, there is no clear right or wrong answer here.
Personally, I agree with your coworker, why copy the whole theme, that is hundreds of lines long, just to change a handful of classes?
That said, I don't personally like the styles living in the DOM under a style tag.
Why not create a new CSS file that contains the styles:
.skin-blue .main-header .navbar{
background-color:#bdac3c
}
.skin-blue .main-header .navbar .sidebar-toggle:hover{
background-color:#ac9b2b
}
.skin-blue .main-header .logo{
background-color:#bdac3c;
}
… // and other classes
And then as long as you include this file after the base skin-blue CSS theme, your updated staff skin changes will take precedence.
Something like this:
<link rel="stylesheet" href="{{ asset('css/skin-blue.css') }}">
#if (get_guard() === 'staff')
<link rel="stylesheet" href="{{ asset('css/skin-staff.css') }}">
#endif
This keeps the abstraction of your CSS inside CSS files (and out of the DOM), yet only overwrites exactly what it needs to.
It also means that if you need to update a common style between the two themes, you don't need to make the change in two different files; you just need to modify the skin-blue.css file.

Angular Material 2 - Disable Ripple?

I'm currently working with md-tab-group (just updated to latest version yesterday)...
Does anyone know
if it is possible to disable/configure Ripple on existing components (md-tab-group in this case)? Latest version causes my tab headers to jump because ripple is calculating large values, solution is to add a small value for md-ripple-max-radius for md-tab-label directly in the template of MdTabGroup.
if there are plans to remove min-width for md-tab-labels? I'm working with a quite small tab group (only 300px width), therefore 160px min-width is not usable.
Thank you!
Use disableRipple as an attribute to disable ripples for the md-tab-group as Angular2+ using the Angular material.
Just simply do something like this:
<md-tab-group disableRipple></md-tab-group>
Also if you are using the latest Angular Material, it's a little bit different like this below:
<mat-tab-group [disableRipple]="true"></mat-tab-group>
I came up with two ways to override md styles based on another post. I had the exact same problem for tabs being too wide in a small tab group. It is still very experimental and might need further explanations but it has worked for me.
First solution using Sass styling
You can use /deep/ before the class you are trying to override
/* your-component.component.scss file*/
/deep/ .md-tab-label {
min-width: 0px; /* Or whatever value you wish */
/* In some situations !important seems necessary */
}
<!-- your-component.component.html -->
<!-- Template from Angular Material's Github Readme.md -->
<md-tab-group>
<md-tab>
<template md-tab-label>
The <em>best</em> pasta
</template>
<h1>Best pasta restaurants</h1>
<p>...</p>
</md-tab>
<md-tab>
<template md-tab-label>
<md-icon>thumb_down</md-icon> The worst sushi
</template>
<h1>Terrible sushi restaurants</h1>
<p>...</p>
</md-tab>
</md-tab-group>
Second solution with pure css
Create an overrides.css file that you link in your main index.html and then override the material classes here
/* overrides.css */
.md-tab-label ,.md-tab-label-active {
min-width: 0; /* same comments as the first solution */
}
<!-- index.html -->
<link rel="stylesheet" content="text/css" href="overrides.css">
Both are kinda dirty, but the first one provides me a good solution to override a md component's style, keeping the alterations inside the concerned components (consider wrapping those components for local changes only).
If you want to remove ripple and click effect in Angular v15 with Angular material v15 you can do it with the "disableRipple" property and some stylings.
<mat-checkbox
formControlName="yes"
disableRipple
>Yes
</mat-checkbox>
Add styling rule to the styles.scss or styles.css:
.mdc-checkbox__ripple {
display: none;
}

Arrange UI-Elements in HTML (with containers, layouts, etc.)

I'm working on a SAPUI5 application with XML-Views.
Now I want to arrange my buttons for example. They should be arranged so they form a numberpad like on a keyboard.
I only know the layout managers from Java or the layouts of a SAP Web Dynpro where I also used transparent containers.
So how can I arrange my elements in HTML? How can I use layout managers and is there such a thing as a transparent container?
Thanks for any hints! :)
Arranging HTML elements in SAPUI5 is how you would in normal HTML. SAP does emphasize that code in index.html is to be minimal, however, so do your best to keep your coding done inside of your views. Your elements are likely to be contained in <div>, </div> tags, which, like any other HTML tag, can be manipulated using CSS.
You'll need to create a CSS file and reference it in your index.html file like so:
<link rel="stylesheet" type="text/css" href="css/style.css" />.
Additionally, you should be aware of the native SAPUI5 layout controls and use them when you can as opposed to writing up your own solution.
You might find this post useful as well.

Make Nokogiri treat xmlns as an ordinary attribute?

I know how to work with namespaces in Nokogiri, but sometimes, I want to look at how the document is actually specified.
In those cases, it would be nice if Nokigiri could simply act like it knows nothing about namespaces, treat "xmlns" just like any other attribute, and treat elements as if their names are exactly as written (colons and all, when present) and all in the default namespace.
Is there a way to achieve that?
EDIT: Add example
So let's say I'm using Nokogiri to check generated SVG. I want to know that the namespace was specified in the root element using the xmlns attribute, and I want to know that the sub-elements use implicit name-spacing.
<svg version="1.1" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<path d="M 10,10 l 5,20" />
</svg>
If I parse that using Nokogiri, then I can find the "path" element as follows:
svg_doc.xpath('//ns:svg/ns:path', 'ns' => "http://www.w3.org/2000/svg")
That shows me that the file is "correct" in terms of resulting in elements with the expected namespaces, but doesn't let me know anything about how that namespacing was specified.
If I could get a document instance that is completely ignorant of namespaces, then…
I could inquire about the "xmlns" attribute value using svg_doc.root['xmlns']…
and I could find that there is a "path" element child of the "svg" root element and that neither element has namespace qualifier prefix using svg_doc.xpath('//svg/path').
In the "Namespaces" section of "Searching an HTML / XML Document" is the part about using CSS selectors:
Don’t be fooled though. You do not have to use XPath to get the benefits of namespaces. CSS selectors can be used as well. CSS just uses the pipe symbol to indicate a namespace search.
Let’s see the previous search rewritten to use CSS:
#doc.css('xmlns|title') # => ["<title>Example Feed</title>", "<title>Atom-Powered Robots Run Amok</title>"]
When using CSS, if the namespace is called “xmlns”, you can even omit the namespace name. That means your CSS will reduce to:
#doc.css('title') # => ["<title>Example Feed</title>", "<title>Atom-Powered Robots Run Amok</title>"]

How to use .svg files in a webpage?

I want to know how can one actually use a .svg file In a web page?
See svgweb quickstart and the svgweb project homepage for something that works in all browsers including IE (requires flash plugin).
There are many ways to include an existing svg file:
<img src="your.svg"/>
<object data="your.svg"/>
<iframe src="your.svg"/>
<embed src="your.svg"/>
<div style="background:url(your.svg)">...</div>
If all you want to do is to place an SVG image such as a logo or static diagram, you just need to be careful to provide a fallback for older versions of Internet Explorer (i.e. versions 8 and earlier).
The best and simplest method I've found is to use a .png or .jpg for your fallback, placed using a normal img tag. You then wrap the img tag in an object tag, using the data attribute to place the SVG.
<object data="/path-to/your-svg-image.svg" type="image/svg+xml">
<img src="/path-to/your-fallback-image.png" />
</object>
The img fallback is only loaded and used if the browser doesn't understand SVG.
I recommend putting the svg inline into your document (html5 technique). Just open your SVG file, copy the SVG tag and everything insideof it and then paste it into your html document.
<html>
<body>
<svg></svg>
</body>
</html>
It has the advantage that this allows you to use css to style it, like changing the fill color or applying filters to it like blur. Another advantage is that you save one http request for fetching the svg file if it is inside of your document.
If you want for example to change its position using css, then you have to put the css inside of a style attribute. Styles that are in an external css file will not get applied in most browser as this is a security restriction. For example:
<svg id="mySVG" style="position: absolute; top: 200px; left: 200px;"></svg>
This technique is supported by all browsers except IE8 and below as well as the android 2.3 browser and below.
Read the chapter inline SVG for further details:
css-tricks.com Using SVG
developer.mozilla.org SVG In HTML Introduction
If you dont want to put it inline in your page then the best alternative seems to be the object tag and avoid using the embed tag.
Read this for further details about object vs embed vs img tag:
How to Add Scalable Vector Graphics to Your Web Page
http://www.w3schools.com/svg/svg_inhtml.asp
The best example:
<embed src="rect.svg" width="300" height="100"
type="image/svg+xml"
pluginspage="http://www.adobe.com/svg/viewer/install/" />
Caspar's approach is the proper one. However, I would move the fallback to the CSS, since you probably want to apply some styles to the svg file itself...
<object data="/path-to/your-svg-image.svg" type="image/svg+xml" class="logo"> </object>
CSS
.no-svg .logo {
width: 99px;
height: 99px;
background-image: url(/path-to/your-png-image.png);
}`
Raphaël—JavaScript Library. Nice javascript library that is using svg, and gives you a large range of effects!
Also supports most browsers, including IE
I'd like to agree with the answer from "code-zoop". Although this technically doesn't answer your question, it might also be a solution: enter the relevant data straight into the HTML. Either directly as an svg element, or by using Raphaël-JS.
From w3c-schools:
SVG is all suported in In Firefox, Internet Explorer 9, Google Chrome,
Opera, and Safari you can
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black"
stroke-width="2" fill="red"/>
</svg>
</body>
</html>
(end of quote)
And to think even more outside the box, depending on how you want to use it, you can also put your 1-color graphics in a webfont. (see for example iconmoon.io )

Resources