I'm using Kotlin to Javascript plugin and kotlinx.html library to build sample app:
fun main(args: Array<String>) {
window.onload = {
document.body!!.append.div {
a("#", classes = "red") {
+"Link"
}
}
}
}
And I want to paint a link with "red" CSS class to red color.Now I'm using unsage + raw to do it:
document.head!!.append.style {
unsafe {
raw(".red { background: #f00; }")
}
}
How to create CSS class with kotlinx.html DSL? I didn't find any docs related to css DSL.
You cannot use the HTML DSL for creating CSS. There are two possible ways for using css in your HTML.
1) You create CSS files independently and then use the classes as you proposed.
2) Inline the CSS if this is feasible for your app.
h1("h1Class") {
style = "background-color:red"
+"My header1"
}
This results in:
<h1 class="h1Class" style="background-color:red">My header1</h1>
kotinx-html is a DSL for HTML only. So CSS needs to be built separately. What you need is kotlinx.css but it was quite unpopular so it was discontinued. For sure there are few community libraries targeted to that purpose but not sure if they are still alive.
Related
Is there a way to define own list styles for ckeditor. I have found the plugin http://ckeditor.com/addon/liststyle but it lets me choose only things like circle or square.
I want to define own css classes for ol or ul in my application that i can use. For example a class to define more space between list elements. the users of the editor should pick the list class via a context menu like in the nice "liststyle" plugin.
Is there a way to do this?
Confirmed the approach mentioned above works, I am using Drupal, Ckeditor List Style (plugin) and the Ckeditor List Style module (Drupal module).
I needed to make a change to the lang > en.js file to add the appropriate Title in instead of the function as the OP.
cute: 'Cute',
Once that was done, inside the liststyle.js file I updated the existing code to this:
Existing code in liststyle.js file:
commit: function(element) {
var value = this.getValue();
if (value)
element.setStyle('list-style-type', value);
else
element.removeStyle('list-style-type');
}
New code:
commit: function(element) {
var value = this.getValue();
if (value) {
if (value == 'cute') {
element.setAttribute("class", 'cute');
element.removeStyle('list-style-type');
} else {
element.setStyle('list-style-type', value);
}
} else {
element.removeStyle('list-style-type');
}
}
I am dealing with CKEditor to add custom list styling to the liststyle plugin.
I added one new style (you can add more if you like) using the CSS class.
Here's how: in liststyle.js (after de-obfuscating) I insert my .logo class:
..........
function e(c,e){
c.lang.liststyle.logo="My bullet"; // BBoyanov - adding 'My bullet' as title in dropdown list (in current language), otherwise it stay "empty" title
var b=c.lang.liststyle;
........
style:"width:150px",
items:[[b.notset,""],[b.circle,"circle"],[b.disc,"disc"],[b.square,"square"],
[b.logo,"logo"]],//BBoyanov - css class 'logo' as Bullet \,[b.logo,"logo"]\
........
commit:function(a){
var b=this.getValue();b?a.setStyle("list-style-type",b):a.removeStyle("list-style-type");
"logo"==b?a.setAttribute("class",'logo'):a.removeAttribute("class");//BBoyanv set 'logo' as CSS class
........
h={a:"lower-alpha",A:"upper-alpha",i:"lower-roman",I:"upper-roman",
1:"decimal", disc:"disc", circle:"circle", square:"square",logo:"logo"};//BBoyanov \,logo:"logo"\
........
You define the CSS class in ckeditor.css (to be visualised in CKEditor) and in your own CSS file.
If you prefer different titles for different languages, you must put translation in the corresponding language .js file of CKEditor.
It worked for me.
However, probably this is injection because it takes over the allowedContent - need tests and confirmation.
I have a basic question with CSS as am quite new to web development.
Can we apply CSS styles on a web page specific to the URL ?
I know CSS do not have if else conditions like we have for Javascript but I just to check if there is any smart way of doing it. Or it is not at all possible.
For example in javascript you do something like following:
if (window.location.href.indexOf("webpage1.com") > -1) {
.................
...................
................
}
Can we do something similar with CSS as well ?
Please provide me your valuable suggestions.
No. CSS has nothing that can read the URL of the page it is embedded on.
Uniquely identifying pages is usually done by adding an id to the html or body element.
It is not possible to connect CSS with the URL of the page but you can add a class or an id to the HTML element of your pages
HTML:
<html class="subpage">
CSS:
.subpage{ add some rules }
HTML:
<html class="main">
CSS:
.main{ add some different rules}
Its possible if you don't mind running a script after your content gets loaded.
The script could get the hostname and use it as a className to attach to the element you want to change the styles based on the specific url, provided of course that the style are predefined. Example:
HTML
<div id="main">Hello World</div>
...
...
...
<script>document.getElementById("main").className = window.location.hostname.split( '.' ).join( '-' )</script>
CSS
#main {
color : red;
}
#main.fiddle-jshell-net {
color : green;
}
#main.google-net {
color : black;
}
see fiddle
If there are a lot of styles to be updated - to the extent that it would be worth adding an entirely new stylesheet to the bottom of the cascade - simply:
create a new stylesheet (eg. extra-styles.css)
if the condition is true, add a reference to that stylesheet to the DOM
Eg.
if (window.location.href.indexOf('page1') > -1) {
var extraStyles = document.createElement('link');
extraStyles.setAtttribute('rel', 'stylesheet');
extraStyles.setAtttribute('href', '/path/to/extra-styles.css');
document.head.appendChild('extraStyles');
}
I am searching a way to styling shadow DOM from the outside. For example, I would like to set the color of all text in all 'span.special' elements as RED. Including 'span.special' elements from shadow DOM. How I can do this?
Previously there were ::shadow pseudo-element and /deep/ combinator aka >>> for this purpose. So I could write something like
span.special, *::shadow span.special {
color: red
}
But now ::shadow, /deep/ and >>> are deprecated. So, what do we have as a replacement of them?
I did try many methods, including those described here. Since I'm using an external Web Component lib, I don't have access to modify these components. So, the only solution that worked for me was using JS querySelector, like this:
document.querySelector("the-element.with-shadow-dom")
.shadowRoot.querySelector(".some-selector").setAttribute("style", "color: black");
Not the best solution, not suitable for large stylings, but does work for little enchancements.
#John this was tested with Chrome 83.0.4103.116 (still going to test in Safari) and I did for Ionic (v5) ion-toast component. Here is the (almost) real code I used:
import { toastController } from '#ionic/core';
let toastOpts = {
message: "Some message goes here.",
cssClass: "toast-with-vertical-buttons",
buttons: [
{
text: "Button 1",
side: 'end'
},
{
text: "Button2",
side: 'end'
},
{
icon: "close",
side: "start"
}
]
}
toastController.create(toastOpts).then(async p => {
let toast = await p.present(); // this renders ion-toast component and returns HTMLIonToastElement
toast.shadowRoot.querySelector('div.toast-button-group-end').setAttribute("style", "flex-direction: column");
});
There is still no easy way to pierce through the shadow root, but here are 3 ways you can go about it. Just keep in mind that you will need to make changes inside the web component.
Using variables v1 - You will need to pass the property and consume the variable inside the web component.
Using variables v2 - You will need to consume the variable inside the web component.
Using ::part() - You will need to add a part attribute to the element you want to style in the web component. (Note: this pseudo element is well supported but is still in experimental mode, so make sure you're aware of that before using it in production).
Run code sample below for details.
const elA = document.querySelector('custom-container-a');
const shadowRootA = elA.attachShadow({mode:'open'});
shadowRootA.innerHTML = '<style>:host([border]) {display:block;border: var(--custom-border);}</style>'+
'<p>Shadow content A</p>'
const elB = document.querySelector('custom-container-b');
const shadowRootB = elB.attachShadow({mode:'open'});
shadowRootB.innerHTML = '<style>p {display:block;color: var(--custom-color, blue);}</style>'+
'<p>Shadow content B</p>'
const elC = document.querySelector('custom-container-c');
const shadowRootC = elC.attachShadow({mode:'open'});
shadowRootC.innerHTML = '<p part="paragraph">Shadow content C</p>'
/* Normal way of styling */
p {
color: orange;
}
/* Using variables version 1 */
custom-container-a {
--custom-border: 3px solid gold;
}
/* Using variables version 2 */
custom-container-b {
--custom-color: green;
}
/* Using ::part() */
custom-container-c::part(paragraph) {
color: magenta;
}
<p>Light content</p>
<custom-container-a border></custom-container-a>
<custom-container-b></custom-container-b>
<custom-container-c></custom-container-c>
You could use #import css as explained in this answer to another question on SO.
Include the rule inside the style element in the shadow tree.
<style>
#import url( '/css/external-styles.css' )
</style>
Note that the >>> combinator is still part of the CSS Scoping Module Draft.
Well, #import is not a solution if you are working with library web component that you can't change ...
Finally I found several ways to do it:
1) Cascading. Styles of Shadow DOM's host element affect Shadow DOM elements also. Not an option if you need to style a particular element of the Shadow DOM, not every.
2) Custom properties https://www.polymer-project.org/1.0/docs/devguide/styling
If an author of the web component provided such.
3) In Polymer, the have Custom Mixins also https://www.polymer-project.org/1.0/docs/devguide/styling
4) #import, but only for not-library components
So, there are several possibilities, but all of them are limited. No powerful enough way to outside styling as ::shadow were.
I have been long battling this, and I would like to know if any others have feedback. I am about to make a customized library for building web apps quickly, and I want to make sure I use the right approach. I WANT to use this method:
$.fn.someSlider = function(){
var coreStyle = '.slider ul { white-space: nowrap; } .slider ul li {display: inline-block}', coreStyleTemplate = '<style><\/style>';
}
But I feel like hard coding the base CSS into the widget is always frowned upon - instead I see SO users recommending the use of CSS style rules instead of this option. I really really really want that 'it just works' feel, and having to force my users to use a separate style sheet just to get my plugins working... well is annoying!
Just to clarify: I would like to include all base style rules needed for the widgets proper/base functionality to be included inside the script. The user would easily modify the base look of the widget by writing a style rule in their own style sheet.
Example:
Instead of having to look through all the base styles trying to find the font color like this... .slider {display: inline-block; color: #000; someotherconfusingrule : blahblah; }
The user simply starts a new rule with the classes name/selector being used - and then just write the changes to make to the default script styles
They would just write
.slider {color: #000};
Thanks for the help in advance SO!
Nice question! Although I'm not sure what the preferred solution to this would be, I was thinking of the following approach:
Use a IIFE to define your jQuery plugin and enable you to define some private, global variables and functions.
$.fn.pluginName = (function() {
return function() {
...your regular plugins code...
};
}();
Define your plugins CSS as a list of style rules in your plugins code
var rules = [
'.box {' +
' width: 100px;' +
' background-color: #f99;' +
' margin: 10px;' +
' padding: 10px;' +
' font-family: Helvetica, Arial;' +
' text-align: center;' +
'}'
];
Create a private variable that remembers if your stylesheet has already been added to the document
var styleSheetExists = false;
Create a private function that creates a stylesheet using the style rules above and that adds it as the first <style> element in the <head> allowing the user to override styles in their own CSS. See http://davidwalsh.name/add-rules-stylesheets for a good tutorial on how to do this properly
var createStyleSheet = function() {
var style = document.createElement("style");
style.appendChild(document.createTextNode(""));
$('head').prepend(style);
for (var i = 0; i < rules.length; i++) {
style.sheet.insertRule(rules[i], i);
}
};
The first time your plugin is applied to an element check if the stylesheet has already been created and if not create the stylesheet.
var $elements = $(this);
if (!styleSheetExists) {
createStyleSheet();
styleSheetExists = true;
}
$elements.each(function() {
$(this).addClass('box');
});
return $elements;
See http://codepen.io/ckuijjer/pen/FkgsJ for this example. It creates a jQuery plugin called box which simply adds the class box to an element. The class box has a default pink background color defined in its stylesheet which gets overridden by a user defined blue background color.
But please do make this configurable in your jQuery plugin. You want to enable developers to bundle all their css, including your plugins, to optimize resource delivery to the client. Plus injecting stylesheets might be a small performance hit.
It may seem annoying but separating the model, view, and controller is the correct way. You're using jQuery so why not consider how jQuery would approach the situation: a jQuery UI widget like the Accordion comes with several stylesheets, the most important being the base stylesheet and a separate 'theme' stylesheet that (if done correctly) is nondestructive and can be modified without risking the integrity of the widget. You may also want to consider how your favorite plugins are authored and what makes them appeal to you. It's my personal opinion CSS should never be present in JavaScript files however if you've made up your mind, the solution #ckuijjer provided is sound. Hope this helps!
HI,
I'm trying to develop some code in Javascript that adds highlighted text to a class. What I want to achieve with this is the ability of text highlighting with a custom color.
I want it to kind of look like the following:
window.getSelected = "<span class=\"highlighted\">" + window.getSelected + "</span>"
after the above code is executed the selected text's background is surrounded by span tags.
thanks,
fbr
You'll want to look into Range Objects, there is a good summary here:
http://www.quirksmode.org/dom/range_intro.html
Browser compatibility will be an issue, but basically, you can get the current selection in the way you suggest, then convert it into a Range, and use the methods of the Range object to find and split the existing DOM nodes, and insert your own <span> tag containing the selected text.
It's not entirely trivial, and involves getting into serious DOM manipulation, but it's a rewarding subject to get your head around. Enjoy!
If you are talking about styling native selections, use ::selection and ::-moz-selection in CSS.
::selection {
color: ...;
background-color: ...;
}
::-moz-selection {
color: ...;
background-color: ...;
}
Alternatively, if you want to highlight an arbitrary element with a class:
CSS
.highlighted {
color: ...;
background-color: ...;
}
JavaScript
yourElement.className = "highlighted";
excuse my english, do you mean adding a class to a text?
function changeClass (elementID, newClass) {
var element = document.getElementById(elementID);
element.setAttribute("class", newClass); // This is for good browsers
element.setAttribute("className", newClass); //For IE<
}
leave all lines, its harmless if you do that way.
If you are using the jQuery framework you can try with the following code:
var your_color = 'yellow';
$('.your-class').css('background-color', your_color);
If you're not using it I highly suggest you start; it makes things a lot easier, it's very stable and it's used by many popular websites including google and stack overflow itself.