Polymer 1.0 Layout Migration- vertical?= equivalent? - polymer

In polymer 1.1,
Does anyone know if there is a equalivant to
<div layout vertical?="{{mediaQuery}}"
horizontal?="{{!mediaQuery}}">
in polymer 1.0? class$={{foo}} doesn't do it as far as I can see. For instance, something like class$="vertical$={{mediaQuery}}"

Actually class$="{{foo}}" should work. But <div layout wouldn't 'cause the layout is now a class selector in Polymer ^1.0. So you will need to write something like <div class="vertical layout"> to make it work.
Since now string concatenation is not supported, in order to make the selectors dynamic, you need to use a computed binding -
<div class$="{{_computeLayoutClass(mediaQuery)}}">
_computeLayoutClass: function(mediaQuery) {
if (mediaQuery) {
return 'vertical layout';
}
else {
return 'horizontal layout';
}
}

Related

Conditional div with blazor server

Here is what I want to do:
#if (condition)
{
<div class="test">
}
<span class="test2">...</span>
#if (condition)
{
</div>
}
This does not work because the Blazor compiler thinks the div is never closed.
So I need to do this:
#if (condition)
{
<div class="test">
<span class="test2">...</span>
</div>
}
else
{
<span class="test2">...</span>
}
It works fine, but I have a big code redundancy with the span.
How can I do this properly?
Please note div and span are examples. In reality, my code is bigger.
Thanks
What you're seeing is really a Razor syntax issue rather than specifically a Blazor issue. This question and answer cover it well.
So, you can do what you're trying to do in the first example, but there are also other ways of solving that issue, at least one of which is Blazor specific (there are more no doubt):
Make the class conditional
Rather than trying to not render the div, you could make the class itself conditional.
So in the code section of your page you could declare a property:
#code {
string myClass = "";
protected override void OnInitialized()
{
if (condition)
{
myClass = "whatever";
}
}
}
And then use that in your razor:
<div class='#myClass'>
<span class="test2">...</span>
</div>
That way the span is only on the page once.
Split the common code into a separate component
Another approach is to make the common part (the span in this case) into a separate component and then render that component conditionally:
#if (condition)
{
<div class="test">
<YourComponent />
</div>
}
else
{
<YourComponent />
}
That's probably overkill for the span in your example, but makes more sense where the new component would be replacing multiple lines of code.

How can I identify which classes and id are been used in a html document?

Im trying to remove unused classes and id's in my site. Is there a function that I can use in the browser's JavaScript console (or other methods) to filter out the used/unused classes and elements.
Thanks in advance.
Something like this could work:
let classList = ["class1","class2","class3","class4","class5"];
classList.forEach(cl=>checkClasses(cl));
function checkClasses(classToCheck) {
if(document.querySelector('.'+classToCheck)){
console.log(classToCheck+' is being used');
}else {
console.log(classToCheck+' is not being used');
}
}
<div class="class1"></div>
<div class="class2"></div>
<div class="class4"></div>
<div class="class5"></div>

Pass a value from HTML to CSS

I was interested whether can I pass value to the css class from the html?
Like this
Example:
<div class="mt(5)"> Some text </div>
style {
.mt(#mpx) {
margin-top: #mpx px;
}
}
I've heard that such way was possible in Less
No, the way you want it is impossible in either CSS or any of its supersets (like Less and others). It's always HTML that uses values from CSS and not in opposite. Thus you'll need some scripting for what you need.
You can however pass values from HTML to CSS via Custom Properties using inline styles:
.c {color: var(--c)}
.m {margin: var(--m)}
<div class="c" style="--c: blue" >Foo</div>
<div class="m" style="--m: 0 2em">Bar</div>
<div class="c" style="--c: green">Baz</div>
Or even like this:
* {
color: var(--c);
margin: var(--m);
/* etc. */
}
<div style="--c: blue" >Foo</div>
<div style="--m: 0 2em">Bar</div>
<div style="--c: green">Baz</div>
But that method is no way different from styling by the plain vanilla method, i.e.:
<div style="color: blue">
... etc.
It is essentially same ugly and non-maintainable.
Many people try to achieve the goal by generating hundreds of predefined classes like .mt-1, .mt-2, ... .mt-99 etc. (since it's extremely easy thing to do in a CSS-preprocessor). But it's even more ugly solution (I won't bother you with details on why it is so. You'll read about that elsewhere or learn yourself after a few projects).
Maybe this is what you looking for? CSS: Attr()
You can bind the value to an attribute and then get this attribute back in the css, like this:
CSS
<p data-foo="hello">world</p>
CSS
[data-foo]::before {
content: attr(data-foo) " ";
}
Result
hello world
Here is a way of doing that without the use of LESS.
Use CSS variables:
Variables can be declared in the style attribute of the HTML elements.
Then, the CSS will catch the values from the HTML and apply the correct styles.
Add some JavaScript:
The values of the variables can now be dynamically modified.
⋅ ⋅ ⋅
Example of use:
Background color is set in the HTML, (fixed)
Padding of div1 will grow if clicked. (dynamic)
// When clicking on the div1, padding is gonna grow up.
document.getElementById("div1").onclick = function(){
var pad = this.style.getPropertyValue("--pad");
this.style.setProperty("--pad", parseInt(pad) + 1);
}
.divs {
background: var(--bg);
padding: calc(var(--pad)*5px);
}
<div id="div1" class="divs" style="--bg: #ff6; --pad: 1;">div1</div>
<div id="div2" class="divs" style="--bg: #f66; --pad: 2;">div2</div>
⋅ ⋅ ⋅
About CSS variables:
The variable names must begin with -- and are case sensitive.
These variables values are applied to the element and its children.
To use it globally, you can declare it on the body tag.
Here is a link with some examples: https://www.w3schools.com/css/css3_variables.asp

Can i use attributes of element to create style rules?

I'm noot good in english, so the title may seem a bit odd.
I want to use css function attr() like this:
I mean i have a container <div> and an inner <div> that i want to have width depending on data-width attribute. For example this would be great, but this doesnt work:
<div class="container">
<div data-width="70%">
</div
</div>
.container {
width: 600px;
height: 200px;
}
.container div {
width: attr(data-width);
height: 100%;
}
Is there any noJS way to use attributes like that?
UPDATE: Guys convinced me that the JS is the only way to do this :)
That's not a big problem (but that's bad. CSS, why youre so illogical? Is the difference between content:attr(data-width) and width: attr(data-width) so big ?).
One of the guys had an idea to go through the all elements with jQuery.
That's ok, but it is very... local? Don't know how to say it in english.
Anyway, i remaked his code a little bit and here it is:
allowed = ['width','color','float'];
$(document).ready(function () {
$('div').each(function (i, el) {
var data = $(el).data(),style = '';
if (!$.isEmptyObject(data)) {
$.each(data, function (attr, value) {
if (allowed.indexOf(attr) != - 1) {
style += attr + ': ' + value + '; ';
}
})
if (style.length != 0) {
$(el).attr('style', style);
}
}
})
})
Idea is simple:
1. We suppose that style we want to add to an element is the only one. I mean there are no scripts that will try to add some other styles,
2. We create an array of allowed attribute names, we need to avoid using wrong names at the style attribute, for example style="answerid: 30671428;",
3. We go through each element, save its data attributes in an object, check if object is empty, and if not - check every attribute if it is allowed, create a string that contains all styles that we need, and - finally - add our style string to the element as the content of style attribute.
That's all, thanks everybody
I would not advise to use CSS alone since it will not allow you to do what you're looking for... instead use a scripting language (in my case jQuery) to accomplish this functionality for you like so: jsFiddle
jQuery
jQuery(document).ready(function(){
var dataElem; // to store each data attribute we come accross
jQuery('div').each(function(){ //loop through each div (can be changed to a class preferably)
dataElem = jQuery(this); //get the current div
if(dataElem.data('width')){ //make sure it exists before anything further
dataElem.width(dataElem.data('width')); //set the element's width to the data attribute's value
dataElem.css("background-color", "yellow");
}
});
});
HTML
<p>The links with a data-width attribute gets a yellow background:</p>
<div>
w3schools.com
</div>
<div class="me" data-width="50"> <!-- change value to see the difference -->
disney.com
</div>
<div>
wikipedia.org
</div>
Notes on the above:
each, data, width.
Instead of doing data-width, use a class attribute. An html tag can have mutliple classes separated by spaces, so if you wanted to be very precise, you could set up as many classes as you need. For instance:
<div class="w70 h100">
</div>
Then in your css:
.w70{
width: 70%;
}
.h100{
height: 100%;
}
And so on.
Is there any noJS way to use attributes like that?
No, you cannot use CSS to set the width of the element to it's data-width attribute. CSS does not allow for this as attr() is only currently available for the CSS content property which is only available on css pseudo elements (::before and ::after).
How can you achieve this with as little javascript as possible?
This is extremely easy to do using the native host provided DOM API.
Select the elements using Document.querySelectorAll().
Iterate the elements and apply the styles using Element.style which can be retrieved from the data-width attribute using Element.dataset
(Demo)
var items = document.querySelectorAll('#container div'), item, i;
for(i = 0; (item = items[i]); i++) item.style.width = item.dataset.width;

Using XPath to select element with highest z-index

In my Selenium application i try to select an element which has the highest z-index. That value is not defined in the element itself, but on an ancestor node (the nesting level is not known). In addition if an ancestor is not visible by the use of display: none it shouldn't be returned.
Example HTML:
<div class="container" style="z-index: 10">
<div style="display: none">
<!-- this should not be selected because it is invisible (and the z-index is lower than the others) -->
<div myattr="example"></div>
</div>
</div>
<div class="container" style="z-index: 100">
<div>
<!-- this should not be selected because the z-index is lower than the others -->
<div myattr="example"></div>
</div>
</div>
<div class="container" style="z-index: 1000">
<div>
<!-- this should be selected because it is visible and has the highest z-index -->
<div myattr="example"></div>
</div>
</div>
Currently i have a regex that selects all elements with myattr="example" which do not have an ancestor with display: none:
//div[#myattr='example'
and not(ancestor::div[contains(#style,'display:none')])
and not(ancestor::div[contains(#style,'display: none')])]
I need an additional condition to select the element which has the highest z-index, so to speak which is visible on top of others. For each found node it has to be looked at all ancestors until a node with a specific class is found (container in this example). Then return only the element that has highest z-index ancestor.
Is that even possible with XPath?
I tried really hard, but I think you can't achieve this with a single XPath 1.0 expression. You can get close, but not quite there.
You'll need to use some other logic. There's like a thousand different approaches.
For example, get all the container elements, sort them by z-index and test their myattr="example" descendants for visibility:
// Gets all containers - could also be Gets all elements containing z-index
List<WebElement> containers = driver.findElements(By.className("container"));
// Sorts the containers in an descending order by their z-indexes
Collections.sort(containers, Collections.reverseOrder(new Comparator<WebElement>() {
#Override
public int compare(WebElement o1, WebElement o2) {
return getZindex(o1) - getZindex(o2);
}
private int getZindex(WebElement elem) {
String zindex = elem.getAttribute("style").toLowerCase().replace("z-index: ", "");
return Integer.parseInt(zindex);
}
}));
// look for a visible candidate to return as a result
for (WebElement container : containers) {
WebElement result = container.findElement(By.cssSelector("*[myattr='example']"));
if (result.isDisplayed()) {
return result;
}
}
throw new IllegalStateException("No element found.");
EDIT: After you accepted this answer, I returned to the question and came up with an XPath 1.0 solution. It's ugly as hell, will perform poorly and I can't verify its correctness (it works on your example and a few others I tried), so I suggest you to use the WebDriver approach above. Anyway, I'll share it:
Copypastable oneliner:
//div[#myattr='example' and not(ancestor::div[contains(#style,'display: none')])]/ancestor::div[#class='container' and substring-after(#style,'z-index:') > substring-after(../div[not(descendant::div[contains(#style,'display: none')])]/#style,'z-index:')]
Formatted version:
//div
[
#myattr='example'
and not(ancestor::div[contains(#style,'display: none')])
]
/ancestor::div
[
#class='container'
and substring-after(#style,'z-index:')
> substring-after(
../div[not(descendant::div[contains(#style,'display: none')])]/#style,
'z-index:')
]
And a free translation to human language (not a literal one!):
SELECT A VISIBLE <div #myattr='example'> NODE
//div
[
#myattr='example'
and not(ancestor::div[contains(#style,'display: none')])
]
THAT HAS A <div #class='container'> ANCESTOR
/ancestor::div
[
#class='container'
WHOSE z-index IS GREATER THAN z-index...
and substring-after(#style,'z-index:')
> substring-after(
...OF ALL VISIBLE SIBLINGS
../div[not(descendant::div[contains(#style,'display: none')])]/#style,
'z-index:')
]
I assumed you know the highest value of z-index, in that case xpath is
"//div[contains(#style,'1000')]/div[not(contains(#style,'none'))]/div"
Otherwise using below xpath get all style attributes of div
List<WebElement> divTags=driver.findElements(By.xpath("//div[not(contains(#style,'none'))]/parent::div[contains(#style,'z-index')]"))
for(WebElement ele:divTags)
{
ele.getAttribute("style");
}
Store the z-indexes in some variable
Parse stored z-indexes and get the numbers alone
Using some logic find the highest number among those
Doing all the above things have the hold on index of that elements.
After finding highest z-index, get the index of that element
Using that index construct xpath.
I hope above logic will help you to achieve your goal.