Jade: Best practice with classes and ids - html

I've searched for a while now, but I couldn't find an answer.
To create a div container with a class or id in Jade you can write:
.foo
#bar
or
div.foo
div#bar
Another thing is multiple classes:
div.foo.bar
or
div(class="foo bar")
What's best practice or is it just personal preference?

It is just a shorthand notation. Nothing wrong with it, just more readable for users who are unfamiliar with the shorter syntax to implicitly show that you are creating a div.
In some cases, using a shorthand syntax however causes the interpreter to perform better, because it works a bit different under the hood.
I'm not familiar with how Jade works, but maybe using just the dot notation saves some work behind the scenes, whilst using the more explicit instructions takes more time to parse.
Same as something similar in css:
border-style: solid;
border-width: 1px;
border-color: red;
/* shorthand */
border: 1px solid red;
Or javascript:
var foo;
if (true){
foo = "bar";
} else {
foo = "not bar";
}
// shorthand
var foo = true ? "bar" : "not bar";
var x = x + 1;
// shorthand, and might uses the processor or engine differently
var x += 1;

Related

Is possible create a css class name with numbers "from-to"?

I need to have 3 classes as follow:
.class-4, .class-5, .class-6 {
color: pink;
}
And it works perfectly.
Let's say I need the same but for 100:
.class-4, .class-5, .... .class-100 {
color: pink;
}
Is there anything similar to this or any other way to do this which I can use.
.class->3<101 {
color: pink;
}
To get the same result without writing 97 times the class and the comma?
There is nothing in pure CSS which will do this, but you could use JavaScript to create a stylesheet for you which has all that tedious repetition created automatically.
In this snippet you say what the ends of the class ranges are and what styling is to be put in each of the ranges.
If there is a range which you don't want to alter then you still need to include it but make its styles string just an empty string.
The snippet runs through each of the ranges creating the relevant style sheet entries and puts them in a style element in the head element of the document.
A few fairly random divs are shown here just to test that we are hitting the right ranges.
const rangeEnds = [4, 20, 35, 41, 48, 100];
const styles = ['color: pink;', 'color: red; background-color: black;', 'color: green;', 'color: yellow;', 'color: blue;', 'color: black; background: pink;'];
let lastRangeEnd = 0;
const styleEl = document.createElement('style');
for (let i = 0; i < rangeEnds.length; i++) {
for (let j = lastRangeEnd + 1; j < rangeEnds[i]; j++) {
styleEl.innerHTML += '.class-' + j + ',';
}
styleEl.innerHTML += '.class-' + rangeEnds[i] + '{' + styles[i] + '}';
lastRangeEnd = rangeEnds[i];
}
document.querySelector('head').append(styleEl);
<!doctype html>
<html>
<head>
<title>Classes</title>
</head>
<body>
<div class="class-1">ABCD</div>
<div class="class-19">ABCD</div>
<div class="class-21">ABCD</div>
<div class="class-40">ABCD</div>
<div class="class-41">ABCD</div>
<div class="class-48">ABCD</div>
<div class="class-100">ABCD</div>
</body>
If all elements will have the same property which is {color:pink}
You can create only one class (lets call it .pink)
.pink {
color: pink;
}
and then you can simply give your elements the .pink class.
One of class attribute's main purpose is to define a shared style reference name. It is rather not a very good practice to want to reference multiple class references and let them share the same styling.
The best way to get around this is to have a common class attribute name YourClassName. This way, any element you want the styling applied to can have that class appended to its class attribute through element.classList.add(YourClassName) with JS. And, that would solve all the hussle of having to worry about putting multiple classe names and I cannot think of any 1 situation that would force you to declare each element class separated by commas provided that they are to receive the same styling.
The OP asks if it’s possible to have a ‘number range’ (array) at the end of CSS classes that shares the same name, but ending on 1, 2, 3, etc.
As #zer00ne pointed out; You can target multiple classes with one "class". When defining your class selector - leave out the numbers, but make the class name unique.
So, if the class names are i.e. my-row-class-1, my-row-class-2, etc., write the selector like this;
[class^="my-row-class-"] {
color: pink;
}
Pro tip: Instead of using class^= selector, it's possible to do this for id^= as well - and more. Check out the MDN web docs for more info.

Show ordered list in Russian alphabets/numerics [duplicate]

There are many possible values for list-style-type CSS property (e. g. decimal, lower-latin, upper-greek and so on). However there are none for the Cyrillic alphabet (which, btw, has different variations for different languages).
What is the best way to style an ordered list with Cyrillic letters?
(I'm providing a solution I ended up with despite I'm not very happy with it.)
I know nothing about Cyrillic list schemes so I’m at risk of a bit of cultural embarrassment here, but CSS3 Lists module (still in working draft) defines quite a few Cyrillic alphabetic list types: lower-belorussian, lower-bulgarian, lower-macedonian, lower-russian, lower-russian-full, lower-serbo-croatian, lower-ukrainian, lower-ukrainian-full, upper-belorussian, upper-bulgarian, upper-macedonian, upper-russian, upper-russian-full, upper-serbo-croatian, upper-ukrainian, upper-ukrainian-full. As expected, the state of support for these is deplorable currently (certainly nothing in Gecko or WebKit), but hopefully going forwards these will start to be implemented.
Update: some changes have been made – the definition of list types has been moved into the CSS3 Counter Styles module whose current draft (Feb 2015) has unfortunately lost all alphabetical Cyrillic types. This is in Candidate Recommendation stage so it’s unlikely that additions will be made at the point. Perhaps in CSS4 List Styles?
In this method I'm using CSS-generated content in before each list item.
.lower-ukrainian {
list-style-type: none;
}
.lower-ukrainian li:before {
display: inline-block;
margin-left: -1.5em;
margin-right: .55em;
text-align: right;
width: .95em;
}
.lower-ukrainian li:first-child:before {
content: "а.";
}
.lower-ukrainian li:nth-child(2):before {
content: "б.";
}
/* and so on */
Disadvantages
Hardcoded, restrict list to a certain max length.
Not pixel-perfect as compared to a regular order list
Here is another solution for Cyrillic letters with pretty clear code: jsfiddle.net
(() => {
const selector = 'ol.cyrillic',
style = document.createElement('style');
document.head.appendChild( style );
'абвгдежзиклмнопрстуфхцчшщэюя'.split('').forEach((c, i) =>
style.sheet.insertRule(
`${selector} > li:nth-child(${i+1})::before {
content: "${c})"
}`, 0)
);
})();
PS. You can convert this next-gen code to old one with Babel: babeljs.io
I'm surprised that there is no Cyrillic numbering. Here's a quick JS solution for you:
function base_convert(n, base) {
var dictionary = '0123456789abcdefghijklmnopqrstuvwxyz';
var m = n.toString(base);
var digits = [];
for (var i = 0; i < m.length; i++) {
digits.push(dictionary.indexOf(m.charAt(i)) - 1);
}
return digits;
}
var letters = {
'russian': {
'lower': 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя',
'upper': 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
}
}
$('ul, ol').each(function() {
if (!(results = $(this).prop('class').match(/(upper|lower)-([a-z]+)/i))) return;
var characters = letters[results[2]][results[1]];
$('> li', this).each(function(index, element) {
var number = '', converted = base_convert(++index, characters.length);
for (var i = 0; i < converted.length; i++) {
number += characters.charAt(converted[i]);
}
$(this).attr('data-letter', number);
});
});​
My written Russian is admittedly bad, as you can see by my inability to count with letters, so change the letters object appropriately.
Demo: http://jsfiddle.net/JFFqn/14/

vue - inserting rows and columns into a table with scoped css

So I'm trying to insert rows and columns into a table using the code below:
add_to_table(type) {
switch (type) {
case "row":
let columns = this.$refs.table.rows[0].cells.length;
let row = this.$refs.table.insertRow(-1);
row.height = "20px";
for (let i = 0; i < columns; i++) {
let cell = row.insertCell(-1);
cell.innerHTML = " ";
}
break;
case "column":
for (let row of this.$refs.table.rows) {
let cell = row.insertCell(-1);
cell.innerHTML = " ";
}
break;
}
}
However, this doesn't seem to maintain the css (doesn't add the data-* stuff to it).
I'm currently working around this by using v-for:
<tr v-for="row in rows">
<td v-for="column in columns">
</td>
</tr>
https://codesandbox.io/s/8n728r5wr8
Your created rows and columns are not getting styled because the <style> you declared is scoped.
For the elements to get the scoped style, they must have a data-v-SOMETHING attribute. The elements you create manually, not via Vue, don't have that attribute.
WARNING: Vue is data-driven, the correct, simplest, more predictable
and maintainable way of achieving what you want is mutating a data
attribute and letting Vue's templates react to it accordingly (using
directives like v-for). Your solution is not optimal. You have been warned.
That being said, you have some options:
Declare an additional <style> (non-scoped) tag along the scoped one. The created elements will pick up these styles. Drawback: the styles will be global. Advantage: you don't depend on Vue internals, you don't have to always add the data-v attribute (see below).
Example:
<style scoped>
...
</style>
<style>
/* EXAMPLE OF GLOBAL STYLE ALONGSIDE A SCOPED ONE */
tr, td {
box-shadow:inset 0px 0px 0px 1px orange;
}
</style>
Get a hold of the data-v-SOMETHING attribute. It is available at this.$options._scopeId. Double Warning: the prefix _ means it is internal code. It may change without notice. Your app may be forever stuck with the current Vue 2.x versions. You have been warned again.
So, whenever you create elements, just add the attribute. Example:
// row example
let row = this.$refs.table.insertRow(-1);
row.setAttribute(this.$options._scopeId, ""); // <== this adds the data-v-XYZ attr
...
// cell example
let cell = row.insertCell(-1);
cell.setAttribute(this.$options._scopeId, ""); // <== this adds the data-v-XYZ attr
Here's a CodeSandbox demo containing examples for both alternatives.

SCSS: Send Attribute and Value to Function

Note:
I'm new to web development and object oriented programming. I am brand new to SCSS and haven't yet grasped a solid understanding of the syntax. I have a basic understanding of how to use functions in SCSS.
Let me start off by defining the result I want to achieve.
_body.scss
body {
background-color: red;
}
Now I know if I wanted to obtain this result in Javascript I could:
Option 1: write a string of HTML code and replace the existing html tag.
Not going to code this, as this is a messy way of writing Javascript, but essentially using document.write() method.
Option 2: use the "setAttribute()" method
// assuming <head> and <body> are the only tags within <html>
var bodyTag = document.firstElementChild.lastElementChild;
bodyTag.setAttribute( "bgcolor", "red" );
I know there are additional ways to do this in Javascript, but for this example, I will focus on these two.
So I want to create a SCSS function that can return both the attribute and the value.
_body.scss ( Pseudocode string example )
#function makeAttribute( $attribute, $value )
{
#return $attribute + ":" + $value + ";";
}
body {
makeAttribute( background-color, red );
}
I have yet to find a built in function that addresses this ( similar to the "setAttribute()" method in Javascript ), or the string example above.
I know that functions can take: number, string, bool, color, list, map or null; but what I don't know is if an attribute fits into any of these value types ( for instance: string ).
I feel as if the article: Bringing Configuration Objects To Sass may be explaining what I am trying to do, but I'm having difficulty understanding this article ( so it may not be an explanation to a solution ).
My end goal is to create a function that would write the following css. I did not mention the browser support previously as it adds another layer of complexity that may or may not be easily explained.
body {
background-color: red;
-o-background-color: red;
-ms-background-color: red;
-moz-background-color: red;
-webkit-background-color: red;
}
i don't know if this have to be a function, i found it more logic use a mixin instead:
// Option 1
#mixin makeRule($value: red, $property: background-color) {
#{$property}: $value;
}
// Option 2:
#mixin makeRuleWithPrefixes($value: red, $property: background-color) {
#{-ms- + $property}: $value;
#{-o- + $property}: $value;
#{-moz- + $property}: $value;
#{-webkit- + $property}: $value;
#{$property}: $value;
}
/////////
body {
#include makeRule;
}
article {
#include makeRule(black);
}
p {
#include makeRule(2px solid blue, border)
}
span {
#include makeRuleWithPrefixes;
}
i changed the name, because is no right say - makeAttribute, when you are creating a cssRule ( selector + property name + property value ), well this is up to you ;)
ok the first,you need interpolation to use a variable as a property name.
The value is the first argument, so now you can use the default property, and just pass different values ( like the article :) )
or you can now set all the properties you want it, just pass the property as the second value ( like p )
body {
background-color: red;
}
article {
background-color: black;
}
p {
border: 2px solid blue;
}
span {
-ms-background-color: red;
-o-background-color: red;
-moz-background-color: red;
-webkit-background-color: red;
background-color: red;
}
I made the option two, because you ask it but i warn you, this is not a good approach. You could use a build tool ( webpack, gulp, grunt.. whatever ) than use a autoprefixer package that do this prefix automatically, this way is a pain because you have to be updating the #mixin eventually.

Are there examples of deprecated HTML elements that lost support in current browsers?

Most of us know that now and then some tags get a deprecated status, which means that it has been outdated. Either it is followed by a newer HTML construct, or it can be done in CSS (take for example <center>). The question that I'm wondering about, though, is: when a tag or element gets deprecated will it be removed from browser support in the future? In other words, currently all browsers that I know of support <center>, but I can imagine that it might not be efficient for browsers to keep supporting deprecated content. Therefore, support must drop after some time.
Is it likely that browsers drop support for a tag or element that once was quite common? To provide a question that's better suited for the SO question-answer template, I'll rephrase all of the above: are cases known where browsers have dropped support for a property or element that once was common?
The only thing that I could find was in the docs, stating:
Deprecated A deprecated element or attribute is one that has been outdated by newer constructs. Deprecated elements are defined in the
reference manual in appropriate locations, but are clearly marked as
deprecated. Deprecated elements may become obsolete in future versions
of HTML.
User agents should continue to support deprecated elements for reasons of backward compatibility.
Definitions of elements and attributes clearly indicate which are
deprecated.
As I see it, this is not opinion based. I am asking if there are cases known of tags that are actually not being supported by browsers any more. That's not bound by opinion. However I do understand that this question has quite an open feel to it. Therefore I'd like to clarify that I am looking for actual and factual evidence of browsers dropping support. I'm not asking about any foreseers to come forward and confess their magical powers, I'm merely looking for examples from cases that have occurred in the past.
The code below creates elements from deprecated tags, and it outputs what the browser thinks the newly-created elements really are:
var dep = 'acronym|applet|basefont|bgsound|big|blink|center|dir|font|frame|frameset|hgroup|isindex|listing|marquee|menu|multicol|nextid|nobr|noembed|noframes|plaintext|s|spacer|strike|tt|u|xmp'.split('|'),
s = '<table>',
els = [];
dep.forEach(function(val) {
var el = document.createElement(val),
str = el.toString().slice(8, -1),
style = 'HTMLElement HTMLPhraseElement HTMLBlockElement HTMLPreElement HTMLSpanElement HTMLDivElement'.indexOf(str) > -1 ? 'background:yellow' :
str === 'HTMLUnknownElement' ? 'background:orange' :
'';
el.innerHTML = val;
els.push(el);
s += '<tr style="' + style + '">' +
'<td>' + val +
'<td>' + str +
'<td>';
});
s += '</table>';
document.getElementById('list').innerHTML = s;
var td = document.querySelectorAll('td:last-child');
dep.forEach(function(val, idx) {
td[idx].appendChild(els[idx]);
});
table {
font: 12px verdana;
border-spacing: 0px;
border: 1px solid black;
}
td {
border-right: 1px solid #ddd;
border-bottom: 1px solid #bbb;
}
<div id="list"></div>
We can assume that anything highlighted in orange is not supported by that browser, anything highlighted in yellow is iffy, and the rest should be completely supported.
To determine the degree of "iffyness" of the generic "HTMLElements," we could compare their default CSS styles to the default styles of a span or div element. The Snippet below does this by adding a new column to the listing, which shows styles distinct to each deprecated element.
Elements of type "HTMLUnknownElement" have no distinct styles (as expected). Most other elements do. For those that don't, that doesn't necessarily mean they don't support distinct attributes. For example, the font element's styles match the default styles of a span – but the font element supports attributes size and face, which the span does not support.
function getStyles(el) {
var gcs= getComputedStyle(el),
st= gcs.cssText ? gcs.cssText.split(/; */) : el.currentStyle,
obj= {},
i, j, sp;
for(var i = 0 ; i < st.length ; i++) {
sp= st[i].split(':')[0];
if(j = gcs.getPropertyValue(sp)) {
obj[sp]= j;
}
}
return obj;
} //getStyles
function compStyles(st1, st2) {
var s= '';
for(var i in st1) {
if(st1[i] && st1[i] !== st2[i]) {
s+= i+': '+st1[i]+' - '+st2[i]+'; ';
}
}
return s;
} //compStyles
var dep= 'acronym|applet|basefont|bgsound|big|blink|center|dir|font|frame|frameset|hgroup|isindex|listing|marquee|menu|multicol|nextid|nobr|noembed|noframes|plaintext|spacer|strike|tt|xmp'.split('|'),
s= '<table>',
els= [],
spanStyles=
getStyles(
document.body.appendChild(
document.createElement('span')
)
),
divStyles=
getStyles(
document.body.appendChild(
document.createElement('div')
)
);
dep.forEach(function(val) {
var el= document.createElement(val),
str= el.toString().slice(8,-1),
display,
style= 'HTMLElement HTMLPhraseElement HTMLBlockElement HTMLPreElement HTMLSpanElement HTMLDivElement'.indexOf(str)>-1 ? 'background:yellow' :
str==='HTMLUnknownElement' ? 'background:orange' :
'';
document.body.appendChild(el);
display= getStyles(el).display;
el.innerHTML= val;
els.push(el);
s+= '<tr style="'+style+'">'+
'<td>'+val+
'<td>'+str+
'<td>'+display+
'<td>'+compStyles(
getStyles(el),
display==='block' ? divStyles : spanStyles
)+
'<td>';
});
s+= '</table>';
document.getElementById('list').innerHTML= s;
var td= document.querySelectorAll('td:last-child');
dep.forEach(function(val, idx) {
td[idx].appendChild(els[idx]);
});
table {
font: 12px verdana;
border-spacing: 0px;
border: 1px solid black;
}
td {
vertical-align: top;
border-right: 1px solid #ddd;
border-bottom: 1px solid #bbb;
}
<div id="list"></div>
It has happened before.
The <blink> HTML tag (see wiki and docs) used to be quite common, but it was considered very user-unfriendly and therefore became deprecated. Netscape, Opera and also Firefox used to support it. Firefox was the last to finally completely remove it in version 23.
The <blink> element was exceptionally obtrusive and became very unpopular, so the drop in support was no surprise... but it is also a question of backwards compatibility. Do the benefits of removing something outweigh the loss of its functionality? <blink> could be removed without much repercussion (things would just stop blinking). On the other hand, a tag like <marquee> (which has also received a lot of negative press) is still supported, most likely because removing it may effect content directly.
All in all I think that the issue isn't really if existing browsers will remove deprecated css/html (since it is a relatively rare occurrence), but rather whether new/future browsers will support them. Backwards compatibility will only go so far.
To sum up: Yes, so don't use deprecated features.