Usage of Polymer 1.0 paper-styles Element - polymer

Unfortunately, I'm finding the current documentation/examples for the usage of paper-styles a bit lacking. I'm not an experienced CSS guy (relative newbie actually), so I could really use examples of how to implement Polymer 1.0 application-wide styling in order to be used by all of it's custom elements (i.e. by applying classes to any tags in those custom element's local DOMs). I did this kind of thing relatively easily in Polymer 0.5 using core-styles, but it has changed enough in 1.0 to confuse me, particularly without full docs/examples to work from. It also seems there may be a few ways to accomplish this. I'm also wondering if paper-styles is still considered experimental in 1.0? There are no docs or examples for it's use in polymer 1.0 online element catalog (https://elements.polymer-project.org/elements/paper-styles), although I did come across 'some' on it's gitHub repository.

The general misunderstanding seems to be, that just by importing the paper-styles element, the document gets styled according to the material design specs. That's not the case.
You just get all the variables and mixins.
Then you need to apply them to each and every element inside your custom-element the way you see it fit.
Here is an example element:
<dom-module id="demo-element">
<template>
<style>
:host {
display: block;
background: var(--paper-blue-500);
padding: 20px;
}
.title { #apply(--paper-font-title); }
button { #apply(--paper-font-button); }
</style>
<h1 class="title">Hello World</h1>
<button>Demo</button>
</template>
<script>
Polymer({
is: 'demo-element'
});
</script>
</dom-module>
Luckily the styles are nicely structured inside just four files with each just a couple of hundred lines max.

One thing you can do when documentation is lacking is search through other projects that are using the code you would like to use. paper-tabs, for example, uses paper-styles. You can see an example import of paper-styles/color.html in paper-tabs.html. The value --paper-yellow-a100 is being used in paper-tabs.html. Below is an example of using various CSS variables (var) and mixins (#apply) defined in paper-styles to apply style to the main document.
<!DOCTYPE html>
<html>
<head>
<title>paper-styles Example</title>
<script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html" />
<link rel="import" href="bower_components/paper-styles/paper-styles.html" />
<style is="custom-style">
.shadow {
#apply(--shadow-elevation-16dp);
}
section {
background-color: var(--google-blue-700);
}
p {
#apply(--paper-font-display3);
}
</style>
</head>
<body>
<section class="shadow">
<h1>Example</h1>
<p>
This is an example using <em>paper-styles</em>.
</p>
</section>
</body>
</html>
Click here to learn more about styling in Polymer 1.0.
Concerning your question about paper-styles being experimental, on the Polymer home page in the catalog section it states:
Custom elements, built by the Polymer team, ready to use in your
applications.
However, in various locations on the site, including styling, there are mentions of experimental features.
the custom properties shim included in Polymer includes an
experimental extension
At this time using #apply would be considered experimental.
There is a page on the Polymer website titled Experimental features & elements you can look at for more information.

Related

How to embed a scoped html (css) in a document

I need to be able to embed HTML snippets (nested elements and CSS) fetched from a remote api inside my document, in a way that their CSS won't affect on my whole document.
I need to fetch (random) gmail messages HTMLs and embed them in my website. The thing is that most messages have their CSS tags to style the message html. The problem is that some of these CSS mess up with my own document CSS. How can I embed an html snippet with CSS, in a way that it will have its own scope and not interact with what's outside of it?
<html>
<body>
<h1>Your gmail messages</h1>
<div id="gmail-message">
<!-- Here to be injected automatically. Changing classes, etc is not possible -->
<h1>This a gmail message</h1>
<style type="text/css">
h1 {
color: red;
}
</style>
</div>
</body>
</html>
The h1 tag outside the gmail-message div is also affected and is therefore red.
What do I need to do to get around this?
One solution would be to use an iframe.
Another solution would be to extract all css and html, then add an attribute (example: scope) to every html tag inside of gmail-messag.
Then modifiy the css and add an attribut selector.
Example:
<html>
<body>
<h1>Your gmail messages</h1>
<div id="gmail-message">
<!-- Here to be injected automatically. Changing classes, etc is not possible -->
<h1 scoped>This a gmail message</h1>
<style type="text/css">
h1[scoped] {
color: red;
}
</style>
</div>
</body>
</html>
But propably using an ifram is a more easy solution.
Easiest way is to use iframe / object / embed tag (tested on firefox).
If you can use Javascript and HTML5 you can also use shadow DOM or make custom element that uses slot tag (also in shadowRoot).
You might want to look into using The Shadow DOM
An important aspect of web components is encapsulation — being able to
keep the markup structure, style, and behavior hidden and separate
from other code on the page so that different parts do not clash, and
the code can be kept nice and clean. The Shadow DOM API is a key part
of this, providing a way to attach a hidden separated DOM to an
element.
However, be aware this is new tech and, as always, Microsoft browsers don't handle it.
I've found my solution.
First, insert an empty iframe tag somewhere.
<iframe id="iframeTag" src="about:blank"></iframe>
Second, load the html snippet into that iframe, the following way:
var doc = document.getElementById('iframeTag').contentWindow.document;
doc.open();
doc.write(<html_snippet>);
doc.close();
This way the <html_snippet>'s css won't mix up with the outer document's.
Use the srcdoc attribute on iframe to scope your HTML and CSS.
<iframe srcdoc="<p>Hello world!</p>"></iframe>
It's supported on all major browsers: https://caniuse.com/iframe-srcdoc

Shared styles and external stylesheets in Polymer 1.1

I've read the new style modules recommendation in Polymer 1.1 and it works beautifully.
My issue here, again, as with the old approach is how could I move all my CSS to a CSS file and not just place it between a <style> tag in the HTML?
Here's an example.
I have a custom <ot-subscribe> element that looks like this:
<dom-module id="ot-subscribe">
<template>
<style>
paper-input {
--paper-input-container-underline: {
display: none;
};
--paper-input-container-underline-focus: {
display: none;
};
}
</style>
<form is="iron-form">
<paper-input placeholder="{{labelPlaceholder}}" no-label-float></paper-input>
<ot-button submit class="button-secondary">{{labelSubscribe}}</ot-button>
</form>
</template>
</dom-module>
As you can see I have a paper-input for which I want to hide the underlines.
This example works just fine.
Now, I need to move that CSS in an external CSS file, but keep it all working exactly the same. So the final markup would look something like this (I've added comments to explain the different approaches I've tried).
<dom-module id="ot-subscribe">
<template>
<!-- Both of these have absolutely no effect -->
<style type="text/css" src="external.css"></style>
<style src="external.css"></style>
<!-- This DOES work, however only for regular CSS, no custom properties or mixins would work -->
<!-- Also, it's deprecated: https://www.polymer-project.org/1.0/docs/devguide/styling.html#external-stylesheets -->
<link rel="import" type="css" src="external.css">
<!-- Using a style module DOES work, however we're just moving the issue, not solving it, since the CSS must still be in the HTML not in an external CSS file -->
<style include="shared"></style>
<form is="iron-form">
<paper-input placeholder="{{labelPlaceholder}}" no-label-float></paper-input>
<ot-button submit class="button-secondary">{{labelSubscribe}}</ot-button>
</form>
</template>
</dom-module>
Why do I need this? One word: Sass.
Has anyone else ever encountered this issue? Has anyone found a solution?
Or to summarize my question, how the heck does one use Sass with Polymer?
As far as I know this is not supported. There are tools available that create style-modules from CSS files automatically though.
https://github.com/Polymer/polymer/issues/2429
build step: https://github.com/MaKleSoft/gulp-style-modules
web service: https://poly-style.appspot.com/demo/

polymer web component #shadow root not displaying

I am trying to run a simple polymer web component on a localhost server on my mac.
I think I have followed the tutorial correctly but the #shadow root information is not appearing within the element tag (as you can see in the image) .
The imports are working because polymer.html is being imported in. I can't figure out why the information is not being displayed with the element I have set up. When I run it in safari the H1 appears briefly (for less than a second) then disappears so this tells me polymer is set up properly it just isn't being pulled into the #shadow root of for some reason...
I have been fighting with this for a couple of days.
any help you can give would ber great and save me many more headaches :)
Cheers guys!!
THIS IS THE OUTPUT ON THE LOCAL HOST SERVER...
<html><head><style>body {transition: opacity ease-in 0.2s; }
body[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; }
</style>
<!-- 1. Load platform support before any code that touches the DOM. -->
<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
<!-- 2. Load the component using an HTML Import -->
<link rel="import" href="bower_components/polymer/polymer.html">
</head>
<body>
<polymer-element name="bens-element" noscript="">
<template>
<h1>This is the shadow dom</h1>
</template>
</polymer-element>
<!-- 3. Declare the element by its tag. -->
<bens-element></bens-element>
</body></html>
<!DOCTYPE html>
<html>
<head>
<!-- 1. Load platform support before any code that touches the DOM. -->
<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
<!-- 2. Load the component using an HTML Import -->
<link rel="import"href="bower_components/polymer/polymer.html">
</head>
<body>
<polymer-element name="bens-element" noscript>
<template>
<h1>This is the shadow dom</h1>
</template>
</polymer-element>
<!-- 3. Declare the element by its tag. -->
<bens-element></bens-element>
</body>
</html>
Safari has no native support for shadow dom yet. It is able to run your polymer application using polyfills. The web component standard is not yet supported on most browsers.
Run the application on Google Chrome. You'll see the #shadow root.
Check this page for information for browser compatibility
unresolved attribute is used to mark that the page is not yet initialised.
Edit:
These are causing you problem -
You're using tagged version of dependencies
I tried building using the versions of dependencies that you're using. Same result. I checked and are just tagged releases. Polymer is still in beta and undergoing heavy development. The latest release from the repo that you should be using are - polymer 0.9.0 and webcomponentsjs 0.6.1
It is the polymer dependency that's causing the behaviour in your case. Because I use webcomponentsjs 0.7.0 for all development. Use bower to resolve your dependencies. Will be simpler if you remove the bower_components folder an bower.json and reinstall the dependencies
The body tag should contain the unresolved attribute.
This is done to prevent unresolved data-bindings and rules from being displayed in the browser. Because custom elements of polymer take time to initialise. Otherwise you’ll see a lot of double moustache symbols - {{}} in page for data bindings and also missing style rules or an empty page.
WebComponents.js adds a style rule for selector body[unresolved] to the page when it is initialised. It sets the opacity to 0 - invisible. So no contents are displayed yet.
After Polymer has successfully initialised all custom-elements, the templates and data bindings resolved, it removes the unresolved attribute.
The page fades into view over 200ms because of another body style rule added on webcoponents initialisation.
Check the head tag for these two style rules added when the page has initialised.

Is there a tool to take css classes and make them inline?

This sounds very backwards, but I want to take existing CSS classes and make them inline in the element itself (The css styles and the html elements are in the same file). There is a reason for this, for which I will not go into detail.
Example:
<html>
<style type="text/css">
.p1 { height: 10px; }
</style>
<body>
<p class="p1">...</p> <!-- Remove class="p1" and replace with style="height: 10px;" -->
<p class="p1">...</p>
<p class="p1">...</p>
</body>
</html>
Keep in mind there can be many CSS classes, and many can belong to a single element.
Edit: The reason I'm doing this is because (based on our client) we want to generate PDF documents from an HTML template. The PDF tool we use does not work well with external CSS classes.
You are looking for Premailer (The source available as well) - it is a Ruby library that does just that (inlines CSS for HTML email - but the output isn't specific to HTML email - it should work just fine with your PDF document generator as well).
There is also lamson.html.HtmlMail if you are using Python and there are a variety of Node.js libraries available to do the same thing.
MailChimp has a page for this in their labs, the CSS Inliner -
http://beaker.mailchimp.com/inline-css
It does leave the class, however.

CSS precedence order? My lecture slides are correct or not?

I've noticed that there are a couple of similar questions and answers at SO already, but let me clarify my specific question here first:
I've got lecture slides which states like this:
http://mindinscription.net/webapp/csstest/precedence.PNG
To be frank, I haven't heard of this rule of css precedence myself, and I googled to find something with similar topic but not quite like that : here
To have a test myself, I've made a test page on my own server here
After running it on FireFox 3.6.3, I am sure it does not show the way as it should be, according to the statement in lecture slides:
imported stylesheet ? am I doing it wrong? I cannot see its effect using FireBug
it says that embedded stylesheet has a higher precedence over linked/imported stylesheets, however, it doesn't work, if I put the linked/imported tag AFTER that.
inline style vs html attributes ? I've got an image where I firstly set its inline style to control the width and height, then use direct html attributes width/height to try modifying that, but failed...
Below is the source code :
<html>
<head>
<style type="text/css">
#target
{
border : 2px solid green;
color : green;
}
</style>
<link rel="stylesheet" href="./linked.css" type="text/css" media="screen" />
</head>
<body>
<div id="target">A targeted div tag on page.</div>
<img src="cat.jpg" alt="" style="width : 102px; height : 110px;" width="204px" height="220px" />
</body>
</html>
Can any experienced CSS guys help me figure out if the slide is correct or not?
Frankly speaking, I am puzzled myself, as I can clearly see some other "incorrect" statements here and there amongst the slides, such as JavaScript is on client-side (how about server-side JavaScript?) and "Embedded styles are in the head section of a web page
"(what the heck? I am not allowed to put it inside the body tag?)
Sorry about this silly question, the exam is on TOMORROW, and I now see a lot of things to think about :)
First, with imported stylesheets they mean stylesheets embedded using the #import rule.
Second, a few lines below that explanation in the CSS 2.1 spec there's an explanation of the cascading order. Other parts of the spec might be useful for your exam, too. Good luck.
Update: A bit of googling resulted in:
http://www.blooberry.com/indexdot/css/topics/cascade.htm
http://monc.se/kitchen/38/cascading-order-and-inheritance-in-css
http://www.boogiejack.com/CSS_4.html
http://www.communitymx.com/content/article.cfm?page=2&cid=2795D
etc.
The properties by <style></style> are being reassigned by the selector in linked.css.
There is no element with id="div" for imported.css.