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.
Related
We are using SCSS, SCSSModule and BEM naming methodology. I have researched the best structure for nested elements. I've seen different syntaxes and still have question mark in my head. I saw the symbol differences, for example some teams use "block__element_modifier", some use "block__element--modifier". I know basic usage of BEM. We shouldn't nest the elements with multiple underscored syntax(block__element__nested is wrong). Currently we are using BEM like
block__element--modifier
and nested elements are written with extra hyphen prefix.
Think that the card component structure like below
card
----header
----------title
----------subtitle
----body
----footer
and we code the sass like
// example.scss
.card {
&__header {
// some css
&-title {
// some css
}
&-sub-title {
// some css
}
}
}
and its classes' output is:
card
card__header
card__header-title
card__header-subtitle
Most of the answers in stackoverflow and also some of articles don't suggest BEM as above. They suggest like this:
.card {
&__header {
// some css
}
&__title {
// some css
}
&__sub-title {
// some css
}
}
and its output turn into this:
card
card__header
card__title
card__subtitle
But If I apply as in option 2, I can't figure out which element is in which when I only read scss file. On the other hand, we can understand that in the first option. But the disadvantage of the first option is that the elements become more dependent on each other. For example, when a new div comes between nested elements, I need to refactor related nested class names in the jsx file.
(But still think that it is very useful to understand which elements are nested in the scss file.)
The question is, is my BEM naming wrong or is there such a use in community?
Note: I said we use "module.scss" but I didnt give example in that format. I know, I didnt want to confuse with camelCase things in js.
Your naming is not wrong; it works and it satisfies the BEM pattern; but personally I would not recommend it, and would instead recommend the popular approach.
Your current approach encodes the DOM nesting of elements into the class names. If you need to make changes with regard to the nesting -for example you need an additional wrapper somewhere, which from my experience is a rather common occurence- you will need to change all nested class names. I would be immensely annoyed by that.
And a second drawback of your current approach is that it produces rather long class names.
But what I think is really the biggest drawback of it:
It forces you to nest your SCSS exactly like the DOM nesting to be able to build up the class names. This -in my opinion- makes the SCSS unnecessairily complicated.
With the popular approach your nesting depth for the styles can stay shallow and therefore easier to handle by humans, without messing up the braces { } or needing to nest and unnest rules when the DOM structure changes.
In one of my projects we started with your approach and later changed to the popular approach, and I experienced it as an improvement.
One example:
<div className="card">
<div className="card__header">
<div className="card__branding">
<Logo className="card__logo" />
<span className="card__brandname">Nutrax</span>
</div>
<h2 className="card__title">Recommendation for hard working web devs!<h2>
<div>
<div className="card__body">
Try Nutrax for Nerves!
<div>
<div className="card__footer">
<Button className="card__button">Find nearest store</Button>
<Button className="card__button card__button--promoted">Buy online</Button>
<div>
</div>
.card {
&__header {}
&__body {}
&__footer {}
&__branding {}
&__logo {}
&__brandname {}
&__title {}
&__button {
&--promoted {}
}
}
Now move the branding into the body, no problem, the changes are minimal, and you don't even need to change the SCSS.
PS: You mentioned that you use SCSSModules; I'm not sure I understand what that means. I'm well aquainted with css-modules and I use them usually in my react projects, which completely removes the need for BEM and I can just use rather simple class names that will be automatically scoped to my component only.
If that is also the case with SCSSModules in your project I don't see the need to apply BEM.
I have a follow up for the question answered on this link:
ckecked element number in :nth-child css rule
The answer is just what I'm looking for but I can't figure out how to set the first Tab as default when the page loads? In the above link it is said that: "you may call the page with the hash #section1". Can anyone perhaps show me how to do this in code? I have been trying for a long time but can't seem to make this work.
Thanks a lot in advance!
In pure-CSS solution involving :target, you anyway need JS to go to URL with corresponding hash (e.g. location.hash = 'content1').
It's generally more flexible to show all tabs by default (incl. when JS is disabled), and hide/show/switch tabs with JS.
The people that suggested "you may call the page with the hash #section1" refer to the URL: if your page is http://www.yoursite.com/yourpage simply navigate to http://www.yoursite.com/yourpage#content1 (content1 because is the id of the first section in the example you provided).
Personally I don't like this solution because it's not flexible and maintainable but nevertheless it works for your simple example.
I'd go for a js based solution: at the begin I'd show only the first section and on click I'd hide all and show only desired one.
Check this (HTML + CSS + JS with jQuery).
HTML:
The same you provided.
CSS:
section { display: none }
section:first-of-type { display: block; }
JS:
$('a').click(function(){
$('section').hide();
$($(this).attr('href')).show();
});
Of course you don't need jQuery to do this but it was faster to write for me :)
Let me know if this was useful.
Just starting working with LESS today... got a question that I am trying to figure out.
Is there a way to apply a style to an LI that has the same class name as its parent UL, without knowing in advance what that class name is?
For example, here is some HTML:
<ul class="random-classname">
<li class="foo">foo</li>
<li class="random-classname">Select Me!</li>
<li class="bar">bar</li>
</ul>
I want to apply a background color to that second element, without using a specific class name in the CSS.
This only answers your question in a very particular use case, which I suspect is not exactly your use case (as it still requires the class name to be put into the css, it just allows the programmer to potentially let another assign it). I offer it here only because someone else may find useful.
If the scenario is such that one knows the "random" name at compile time, the class name could be set as a variable, and then processed like so:
#randomName: random-classname; //set at compile time
.#{randomName} {
straight-property: value;
& > & {
nested-property: value;
}
}
Which would produce:
.random-classname {
straight-property: value;
}
.random-classname > .random-classname {
nested-property: value;
}
The above might be useful if one were building some type of framework, or dynamically setting the variable via php from user input at some other stage. But I believe you were hoping for some "generic" solution in your actual output CSS, which (as the comments noted) is not currently possible, and as they also noted, javascript is your best bet in such a case.
You are overthinking this. Using the selector .random-classname only, regardless if in LESS or CSS, will select both the ul and li...
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);
}
Want to edit things like DIV size, color, positioning (absolute), height/width etc.
You can just output the CSS like any other with Response.Write or the <%= someValue %> methods.
Here are some of the other methods:
http://cfouquet.blogspot.com/2006/06/making-dynamic-css-content-with-aspnet.html
If by "on the fly" you mean while the user is interacting with the page then you're going to need to use some javascript. I suggest learning jQuery as it provides an easy and effective way interact with the DOM.
Ryan, you may want to look into Themes if you want to change the appearance of your site based on user preferences (Learning about Skins can help as well but master themes first). This is really the right approach in the ASP.NET model unless you are looking just to adapt some specific output to certain data conditions.
I'm not sure of what you're trying to do with the information given, but to add css on the fly you can use jQuery to add the class to an element with those certain specifications.. you can have jquery wait in the background for something to happen on the client and just add the class with that certain style
Example:
<style>
p { margin: 8px; font-size:16px; }
.color { color:blue; }
</style>
<script>
$(document).ready(function(){
$("#button1").click(function(){
$("p:last").addClass("color");
});
</script>
<p>Hello</p>
<p>and</p>
<p>Goodbye</p>