There is a portion of my website where I am using a country's flag as an icon for a list element.
For instance, I have:
<ul>
<li id="at">Austria</li>
<li id="de">Germany</li>
</ul>
The accompanying CSS looks like this:
#at {
list-style-image: url('at.png');
}
#de {
list-style-image: url('de.png');
}
Is it possible to replace this with a macro so that I don't need to redefine the CSS for each country? Something like a C-style macro would be awesome, but I'm not sure if CSS supports this sort of thing.
ie
#_country {
list-style_image: url('_country.png');
}
CSS itself doesn't do this, but you can always serve the CSS from a PHP script or similar, doing the macro processing server-side to generate the separate rules from a list of countries.
Since CSS itself does not have itself a macro system, you always have to write all the rules explicitly. Hence you may choose the server side solution (which adds an extra overhead to the loading), or using your text editor's macro or snippet facilities, you can easily generate the rules by yourself.
An interesting thing would be, if CSS had support for string concatenation and the attr() function to be used outside the content property, so someone could write:
.languages {
background-image: attr(id) ".jpg";
}
Short answer: No.
Longer Answer:
You should not rely on JavaScript for such a feature, since not everyone has JavaScript enabled and it would be like breaking a fly on a wheel...
Except for generating it via PHP, Perl, Python (live on serverside, or just once on your PC and save the file as *.css) or something there isn't anything you can do to save you the hassle of copy / pasting this 3 lines and changing them for each country.
So, just do it the annoying way ;)
If it's only those three lines i think you'll have your list put together very fast.
One of the possible solutions:
<!-- our lovely list-style-image function -->
<script>
function set_list_country(list, country) {
list.style.list-style-image = 'url("'+country+'.png")';
}
</script>
<!-- country list -->
<ul>
<li id="at">Austria</li>
<li id="de">Germany</li>
</ul>
<!-- country list styling -->
<!-- note: this goes below your list, or else create onload function -->
<script>
set_list_country(document.getElementById('at'), 'at');
set_list_country(document.getElementById('de'), 'de');
</script>
Regards.
No, you can't do this in plain CSS because the CSS language hasn't control structures or anything like that wich will allow you to dinamically generate CSS code.
Instead, you can use a javascript solution as Andrejs pointed or a solution based on CSS variables coded in PHP.
Whilst generating the CSS server side in script is an option. I prefer simple javascript here.
Some commenters have pointed out that if JS is not available then users wont see the flags....but what else wont work if js is disabled - just about every '2.0' web site!
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Page</title>
<script type="text/javascript">
function initFlags() {
var flagListItems = document.getElementsByTagName("li");
for (var i = 0; i < flagListItems.length; i++ )
{
var li = flagListItems[i];
// use any prop you want to build the url - i used an expando one
// just because i thought it made the code more readable.
var f = li.getAttribute("flag");
if (f == "" || f == null) continue;
li.style.listStyleImage = 'url(' + f + '.png)';
}
</script>
</head>
<body onload="initFlags()">
<ul>
<li id="at" flag="au">Austria</li>
<li id="de" flag="de">Germany</li>
</ul>
</body>
</html>
You can use CSS for simple macros. Here's the CSS coding for "version" that is referenced several times in one of my documents...
.version::after {
content: "42";
}
...then, anywhere in the document I want to use the current version, this...
<span class="version"></span>
...which results in 42.
Here's one where I set up the "lock" emoji. This might be usable for the country flag, inasmuch as they are mostly available as emojis. CSS requires hex coding of a unicode code-point here, sadly, but still, it's doable...
.lockicon::after {
content: "\01F512";
}
...same kind of invocation...
<span class="lockicon"></span>
...which results in 🔒.
Because the text within the content: ""; is straight unicode, not HTML, things like character entities and HTML tags don't work.
In many cases, however, you can use the unicode code-point for a character entity. For instance, while you can't put — in there, you can put the unicode code-point for it, as in "\0000A0". Be sure to use all six HEX digits, otherwise interpretation by CSS may be incorrect, depending on what else you have in the "content" value.
You can use images, too, but to scale them, you have to use transform: scale(n);
div::before {
content: url(image.jpg);
transform: scale(0.75);
}
Related
What CSS can I use to delete elements only for AMP posts on the website? AMP is an open-source framework, which reduces page size and eliminates javascript, so that website loading times could are less than 1 second.
I know how to hide an element is with display: none .
But I don't know how to implement that only on AMP posts.
This is the class of elements I want to remove only from the AMP post: lwptoc_toggle_label .
Class: lwptoc_toggle_label .
I have written the CSS .lwptoc_toggle_label {display: none} so that the element is removed, but the problem is I don't know how to apply that CSS only to AMP posts.
Can I use this: #media screen and (max-width:480px) {.lwptoc_toggle_label {display: none!important}} ?
Does anyone have an answer?
CSS is an adjective-like language, it is not functional.
JavaScript is the event-driven verb-like language. You need to put script elements inside of the head element if you plan to code professionally or you can just dump it at the bottom of the body element if you don't care about professionalism.
<script defer="true" type="application/javascript">
//<![CDATA[
// Put JavaScript code here, like the code below.
//]]>
</script>
Use Examples
You can then use the unique id attribute to reference an element you want to delete or use other methods of selecting an element. That reference becomes a parameter when calling the element_del function.
element_del('test12');//Instead of document.getElementById('test12')
element_del(document.getElementById('test15'));
element_del(document.getElementsByTagName('div')[4]);
Function
This is the function we use for an entire web platform. We don't use frameworks or libraries because you don't get paid for maintaining poor code.
function element_del(id)
{
if (typeof id=='string' && document.getElementById((id) && document.getElementById((id).parentNode.removeChild)
{
document.getElementById((id).parentNode.removeChild(document.getElementById((id));
}
else if (typeof id=='object' && typeof id.parentNode=='object')
{
id.parentNode.removeChild(id);
}
}
I wonder if triple curly brackets sanitize user input within templates to be XSS safe. <script> tags won't render out, but how about other creepy XSS hacks?
Thanks in advance!
Its not safe, because you can still run malicious code, like this:
Template.xx.helpers({
'bad':function() {
return "CLICK ME PLZ!";
}
});
The template
<template name="xx"> {{{bad}}} </template>
This means the user needs to click the button, but you could make it more of a sure thing by use other events such as onmouseover:
A floating div can take up all the space & use mouseovers to assure the code is run. This can be used as the return value in this example:
<div style="width:100%; height:100%; position: fixed;" onmouseover="console.log('haha');"></div>
You can also have other exploits such as changing page content via CSS (using content: or higher z-index floating divs to change the page's content.
Apparently adding <link rel="stylesheet" ... in the document body is considered a bad practice by W3C standards. The same for adding <style> blocks in the body...
So are there any standard-compliant solutions to add CSS outside of the <head> tag? Like at the end of the document.
If you only want to include your CSS styles on a specific events, there's nothing stopping you from doing so at the head:
var linkElement = document.createElement("link");
linkElement.rel = "stylesheet";
linkElement.href = "path/to/file.css"; //Replace here
document.head.appendChild(linkElement);
This has the added benefit of adding your stylesheet in an async way, which doesn't block the browser from downloading anything else.
One way to solve that issue is to load the CSS with .get() and, appending it to the head tag only when needed:
JQUERY
var css = "foobar.css";
var callback = function() {
alert("CSS is now included");
// your jquery plugin for a navigation menu or what ever...
};
$.get(css, function(data){
$("<style type=\"text/css\">" + data + "</style>").appendTo(document.head);
callback();
});
The callback function is useful to allow script code that depends on the CSS file to be properly formatted, to run only after the CSS as been added!
Only HTML5 allows it with the scoped attribute, but make sure you declare the DOCTYPE correctly.
<style type="text/css" scoped>
.textbox {
color: pink
}
</style>
I think this standard gets largely ignored by most once you start doing things like server side programming or DHTML.
For static HTML files, you definitely can/should follow the rule of only including CSS within the HEAD tag but for conditional output and interactivity it can sometimes simplify things to have conditional styling as well. Consider that in the end, this convolutes the resulting document. Even though browsers may render it just fine, if you yourself were to look at the source, it's just plain easier to read if all the styles defining the layout/display were within the HEAD. There are, of course, a number of other examples and reasons as to why it's bad practice.
The HTML standard exists apart from things like server side scripting and DHTML i.e. it's not the HTML/SSS/JavaScript standard.
If you are talking about an external css sheet, then the correct way is as follows:
<link href="....link to your style...." rel="stylesheet">
If you want to include an inline css, then you just need to do as follows:
<style>
....Your style here...
</style>
Is it possible to create a new property in CSS? For example, say you're developing a control that displays a photo and you want to add a property to css to control what style frame to have around the photo. Something like:
#myphoto { frame-style: fancy }
Is there some way to do this in a cross browser compatible manner, and how would you define whether the style inherits or not?
EDIT: It's a custom control - your JS code would deal with the style - I'm not expecting the browser to magically know what to do. I want the user to be able to style the control with CSS instead of JS.
Sure, why not. Check this out as an example: http://bililite.com/blog/2009/01/16/jquery-css-parser/
You may also be able to get away with using CSS classes instead of properties. Not sure if that works for what you're doing.
You can't. Browsers interpret CSS based on how their layout engines are coded to do so.
Unless you took an existing open source engine like WebKit or Gecko, added custom code to handle your custom CSS and made a browser that used your customized layout engine. But then only your implementation would understand your custom CSS.
Re your edit: it'd depend on whether you're able to read that style somehow. Typically browsers just instantly discard any properties they don't recognize, and CSS is not normally reachable by JavaScript because CSS code is not part of the DOM.
Or you could look at Jordan's answer.
If you'd prefer a straight JavaScript solution that uses no JS libraries, you could use the query string of a background-image to keep "custom properties" inside your CSS.
HTML
<div id="foo">hello</div>
CSS
#foo {
background: url('images/spacer.gif?bar=411');
}
JavaScript
getCustomCSSProperty('foo', 'bar');
Supporting JavaScript Functions
function getCustomCSSProperty(elId, propName)
{
var obj = document.getElementById(elId);
var bi = obj.currentStyle ? obj.currentStyle.backgroundImage : document.defaultView.getComputedStyle(obj, null).getPropertyValue('background-image');
var biurl = RegExp('url\\(["\\\']?([^"\\\']+)["\\\']?\\)').exec(bi);
return getParameterByName(propName, biurl[1]);
}
function getParameterByName(name, qs) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(qs);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
Demo:
http://jsfiddle.net/t2DYk/1/
Explanation:
http://refactorer.blogspot.com/2011/08/faking-custom-css-properties.html
I've tested the solution in IE 5.5-9, Chrome, Firefox, Opera, and Safari.
My HTML is all marked up, ready to make it rain CSS. The problem is that I have to go back and find out what all my id and class names are so I can get started. What I need is a tool that parses my HTML and spits out a stylesheet with all the possible elements ready to be styled (maybe even with some defaults). Does such a tool exist?
I have a poor man's version of this I have used in the past... this requires jquery and firebug...
<script type="text/javascript">
$(document).ready(function() {
$('*[#id]').each(function() {
console.log('#' + this.id + ' {}');
});
$('*[#class]').each(function() {
$.each($(this).attr('class').split(" "), function() {
console.log('.' + this + ' {}');
});
});
});
</script>
it gives you something like this:
#spinner {}
#log {}
#area {}
.cards {}
.dialog {}
.controller {}
if you want them in "natural" page order instead...
<script type="text/javascript">
$(document).ready(function() {
$('*').each(function() {
if($(this).is('[#id]')) {
console.log('#' + this.id + ' {}');
}
if($(this).is('[#class]')) {
$.each($(this).attr('class').split(" "), function() {
console.log('.' + this + ' {}');
});
}
});
});
</script>
I just load the page with that script in there, then cut and paste the results out of firebug... then obviously, remove the script :)
you'll need to remove the dups manually or just toss in some simple dup checking logic with a map or array or something.. one for IDs and one for classes.
When I first saw this, I thought "Great question! Neat answer, danb!"
After a little thought, I'm not so sure this is a good idea. It's a little like generating event handlers for all controls in an ASP.NET page, or generating CRUD procedures for all tables in a database. I think it's better to create them as needed for two reasons:
Less clutter from empty style declarations
Less temptation to misuse (or underuse) CSS by writing everything at the class level rather than using descendant selectors like (#navigation ul li a).
http://lab.xms.pl/css-generator/ seems to fit the description.
I agree with Jon, but I don't see a problem* with doing what the OP wants. Using the script provided, you'd know all of your classes and ids. While working on your CSS, you should be deciding if you need to use each of them. At the end, or at the point that you feel like you have a good handle on what you're doing, run it through an optimizer / compressor so it removes unused ids and classes.
*Operating assumption: You either didn't write the original HTML or you wrote it and later decided that "gosh CSS would be really nice here now, I wish I would have started with it." :-)
Not that it isn't a sensible question with a sensible answer, but it implied to me the kind of unnecessarily marked-up HTML that people create when they don't understand positional selectors: the kind of code where everything has a class and an id.
<div id="nav">
<ul id="nav_list">
<li class="nav_list_item">
<a class="navlist_item_link" href="foo">foo</a>
</li>
<li class="nav_list_item">
<a class="navlist_item_link" href="bar">bar</a>
</li>
<li class="nav_list_item">
<a class="navlist_item_link" href="baz">baz</a>
</li>
</ul>
</div>
you can remove everything except the id on the div and still be able to style everything there by its position; and obviously, the script won't show you all those possible selectors, will it?
In other words, a narrow focus on CSS as something done to classes and ids is a concern.
This blog entry references to something similar to what you need here.
It contains a link to a Perl script called 'stylizator.pl'. This script parses the html to look for possible CSS elements and outputs them to a file.
Another way to approach this is to standardise the id and class names you use in your HTML according to some sort of naming convention.
I disagree with Jon. While this solution can be used poorly in the way he describes, it does not necessarily mean it will. Any wise developer or designer is going to take the script generated css classes and pull only what is really needed into the css file.
The solution still solves the OP's question.
I've made a generator which makes the html and css for you = https://www.andy-howard.com/css-skeleton-screen-generator/
Not much else to say really, it utilises the :empty selector in css.