Hi all, this is my first post and english isnt my native language, so please, be nice and patient. Thanks.

Few weeks ago I started to learn (slowly and patiently) how to install, configure and customize Drupal/CivicSpace.
During this time, I felt sick and angry and very disappointed more than once. But from time to time, while learning Drupal, I have some "insights", and things about Drupal becomes more clear. I'm feeling quite masochist and I dont know why insist with Drupal. It has become a challenge and I really want to fully understand Drupal.

So, after this introduction, I would appreciate if someone can explain me few points about Drupal:

  1. Why there are so many-and-long-and-confusing classes and IDs?
    Example: why I need <div class="block block-user" id="block-search-0">? Why do I need such so-especific classes and IDs if I can stick to a simple line like <div class="block" id="search"> or even <div class="block search"> ?
  2. Has Drupal all this "class and ID high specificity" just to get a hyper-high grade of customization?
  3. Regarding my second question, I find that most sites doesnt need such specificity of classes and ids. If you view the source code and the CSS of most well-coded (xhtml+css) sites -that doesnt use Drupal- you can see there arent tons of classes and IDs... even in the most complex XHTML+CSS sites, a high customization can be achieved with few styles.

    Also, and related with all the above, i have this question: is it safe to to the following?

    In block.tpl.php, I want to change:

    <div class="<?php print "block block-$block->module" ?>" id="<?php print "block-$block->module-$block->delta"; ?>">
      <h2><?php print $block->subject ?></h2>
      <?php print $block->content ?>
    </div>

    to something like (or similar to) this:

    <div class="<?php print "block" ?>">
      <h2><?php print $block->subject ?></h2>
      <?php print $block->content ?>
    </div>

    This way, I'm simplifying the code that Drupal outputs. I want to get a simpler and lighter xhtml valid code.

    If someone can give me some advices about all this topic, some enlightment in Drupal customization, I would really appreciate it.
    Thanks in advance and excuse my english.

Comments

styro’s picture

There are so many classes and IDs so that theme designers can get all the flexibility they need for creating stylesheets.

As for removing extra classes in your templates, it shouldn't be any real problem. Just test all your blocks to make sure they still look ok. Some modules include their own CSS for blocks they provide, and you may find that they will look a little different without their specific classes.

You won't break anything very badly - just satisfy yourself that everything still looks how you want it.

And don't worry about your English - it is very good :)

--
Anton

maniqui’s picture

Thanks, styro, debtman7 and JohnG for answering and sharing your thoughts

First, I have been thinking a suggestion for improve Drupal (is this the place to make suggestions?:

In admin » block » configure, I would be great to have a input text field where you can specify a particular class/ID for each block.
So, if you leave it empty, no special class/ID will be applied to that block.
In the other hand, if you fill it, then, you can manually specify a class/ID to each block, and with the name you want.

So, if you dont fill it, you can get something very simple, like this
<div class="block">...content...</div>

And if you fill it, for example, with "search":
<div class="block" id="search">...content...</div>

This way, you only give specific classes/IDs to the blocks you want. All the rest, just gets the class="block".

Of course, this logic can be applied not only to block, but to any node of content.

styro wrote:

There are so many classes and IDs so that theme designers can get all the flexibility they need for creating stylesheets.

Yes, I can understand that. In fact, I also point that in the first post of this thread. With so-especific class and ids, you can, for example, do absolute CSS positioning to each box, give different colors and bg-colors... etc.

But, in the other side... the page code gets a little overloaded.

Also, there is all this issue and discussion about /misc/drupal.css.
Regarding this, I think this file brings some difficult to the task of customizing Drupal...
and my second critic to Drupal is:

why the user side and the admin side are integrated?
isnt easy to have the admin side in one side and the user interface in other side?

It's already difficult to theme the user side, to also add the task of keeping the admin side nice and styled.

I have to put off my mask: in this few weeks I think I started to hate Drupal because it isnt as simple as I thought I often get frustrated with it and because... I'm also a Textpattern lover and I love the simplicity of Textpattern to output exactly the xhtml code I need, without an unnecesary character, word, class, ID.

I have chosen Drupal (over Textpattern) for some clients because I know it's very elegant and powerful and it has forums and other tools integrated to the core.
But trying to install, learn, understand, modify and customize Drupal is becoming a pain in the *ss-

I wont leave Drupal because, as I said, this has become a challenge to me.

So, in a kind of summary:

  • drupal.css -> please, it would be nice to remove this file in next versions. I want to make my themes from scratch
  • it would also be nice to separate user side from admin side, there is no need to mess all under the same theme. For example, I would like to develope my own theme for user side, but keep the admin side with the default drupal theme, because it looks nice.
JohnG-1’s picture

some are much easier to tinker with than others.

I like friendselectric, but I reckon agreebee would be perfect if you want to start from scratch. Phptemplate themes are definitely the way to go and whatever you do, don't bother with bluemarine ! (the hours I wasted trying to tame that one!)

styro’s picture

In admin » block » configure, I would be great to have a input text field where you can specify a particular class/ID for each block.
So, if you leave it empty, no special class/ID will be applied to that block.
In the other hand, if you fill it, then, you can manually specify a class/ID to each block, and with the name you want.

That seems fine from the point of view of someone who is creating themes from scratch, but keep in mind you are now hard coding a theme to one particular database - things are no longer general purpose or flexible / maintainable. You'll have to do extra work for new modules and features etc, and won't be able to leverage the work of others as easily.

Not everyone creates themes from scratch, I suspect most just tweak a few things here and there. But if you want to drop drupal.css altogether, you can no problem. There have been examples shown about how to do that - if you can't find anything search the mail list archives or ask a specific question about doing just that (I only know it can be done, not how to do it).

Quite often when questions like this are asked, the person is coming from their own point of view without fully considering all the other different ways other people use the system. eg the admin vs user separate interface questions that always comes up. That would work ok for a site where you only had admins and users - but what if you had multiple roles ranging from admins, authors, editors, readers etc etc - how do you define what is an admin interface? It changes depending on circumstances.

Drupal attempts to work better for the general cases rather than a few special cases.

--
Anton

JohnG-1’s picture

I think I agree with you maniqui, css tags often seem like an afterthought for most of the modules that make drupal. My impression is that there probably are too many pointless and useless tags, though I can't be sure of everyone's needs.

I suppose it could be tackled by enforcing a standard scheme for css tag deployment as a drupal standard, but certainly in the short term this would undoubtedly confuse things further!

As for the examples you referred to, I'm guessing that most id and class tags will be generated from bits of the modules and functions that go into creating them
'<div class="block block-user" id="block-search-0">' etc. Simply concatenating tags is much easier than actually thinking about how designers are going to work with them.

CSS works best with fewer tags and ids. That's what its designed for, to avoid the need to write formatting info for every line of html.

My current thinking is that nesting common tags and classes is preferable to concatenating, so<div class="block block-user" id="block-search-0"> could become something like <div class='block'><span id='search'><span class='user-1'> ... . It might look more complicated but it is infact much easier to write cascading style rules for becasue it uses inheritance.

Ok I'm beginning to rant, but yes. I would like to help take this issue further. I think there is room for improvement in drupal's understanding and implemetation of CSS.

Anonymous’s picture

I don't think there are too many css selectors. The big difference is that when you design a website with plain old html, no frameworks or CMS involved, you know exactly what items you need to style and how they may need to be styled differenly. With drupal, the developers don't know they. They don't know if some wacky person like me is going to come along and want to make the table for a certain node type different from all the others, or an unordered list on one page be different from another, etc.

So they have two choices. They can use generic selectors and when someone asks how to do those wacky things, they can say no. Or they can go all out and make it as flexible as possible. By having more than one id it gives the possibility to not only style the generic element, but also a specific use of that element.

styro’s picture

Things might change (a little) once mainstream versions of IE support the full range of CSS selectors and psuedo selectors though. Then you can be much more creative with CSS and less dependent on classes and ids in the HTML.

But until then I'd still prefer to have too many classes than too few.

--
Anton

JohnG-1’s picture

for the example you give:

each page can be given a unique id-tag based on it's URL (see http://drupal.org/node/32077 - the principle seems basically sound) and a table is an html tag.

So if your page is 'drupal/admin/my_dinner', it gets a <body id='page-admin_my_dinner' >

(In the same stroke we can also give it <div class='admin'> which could be very useful...)

the css ref to that instance of a given table would be

#page-admin_my_dinner table { display:none } or whatever.

very simple indeed. or have I missed something?

the significance of css classes is how you combine them; how they overlap - it's more like a grid reference than a landmark.

As for node-types etc, it should be very easy to create class tags for them. I concocted this phptemplate function to give me CSS access to the form items used to build up node-edit pages: http://drupal.org/node/33474. It assigns to each form item an id tag based on the name attribute of a given input field.

gollyg’s picture

i too, am horified by the number of css classes and id's generated by a default php theme. However, I understand why they are there. It allows fairly complex layouts to be created by those who want to control the layout using purely css and default drupal output.
I want control over this aspect of the code, so i modify my theme files accordingly, reducing the classes to just the ones i need. It is time consuming but ultimately worth it.
The alternative would be to give too few selectors to control the layout via css. And i am guessing that the user who doesn't want to use themes in the first place is less likely to go into a theme so that they can modify the html output to include the selectors they need!
The example given of blocks show that drupal php themes offer three default selectors:

  • a class selector for blocks in general
  • a class selector for that particular type of block
  • and an id for that specific block.

Part of the messiness comes from the repetition of 'block', but this is following a certain logic.

nevets’s picture

You example using blocks shows why there are so many classes and ID's and is also a good example of why there are so many.
I can use .block (common to all blocks) to provide css rules that are the default for any block. I can use the class selector for a particular type of block to provide common css rules for all blocks of that type (which might override rules defined with .block). And finally I can provide block specific styling using the ID.

And depending on what you want to do, they can all be useful.

maniqui’s picture

Thanks for all replies.

  • a class selector for blocks in general
  • a class selector for that particular type of block
  • and an id for that specific block.

I already get the point about the 2 classes and 1 id, and that is why I suggested a way where the complexity should be increasing if necesary.
I mean, the templates should start with something as simple as

Then, in the admin, it would be nice to have an input text form in the configuration of each block where you can set a more specific class/id name for that each block.
There are some advantages:

  1. by default, the block just will have a class="block"
  2. only those blocks that the webmaster needs a very specific styling will have an extra class/id
  3. you can use the word you want for the class/id -> would be great for i18n, because with the actual method, all the blocks have english words as class/id...
  4. you can group the blocks as you want. Example, you can give the same class/id to certain blocks (so they are "grouped" by the samen class/id) and style them all with just one declaration in the CSS

but styro wrote:

That seems fine from the point of view of someone who is creating themes from scratch, but keep in mind you are now hard coding a theme to one particular database - things are no longer general purpose or flexible / maintainable. You'll have to do extra work for new modules and features etc, and won't be able to leverage the work of others as easily.

I cant see the problem here (please, be kind, I'm noobie).
I mean, lot of information about drupal (example: the path-alias for clean URLs) are stored in the database.

So, in my suggestion the class/id for each block (and other elements in the page) shouldnt be defined/hardcoded in .tpl.php files nor in the modules. When creating his own theme, the user will have the choice of re-naming classes/id for each element as the user wants, directly from the admin. But even if classes/ids are hardcoded (to easily support and modify default themes), they should be overrideable by re-defining them through the admin, and storing them in database.

To understand, this is similar to the hardcoded welcome in all Drupal installations ("Welcome to your new Drupal...").
This paragraph is hardcoded inside a file and not in the database.
But when you write the first content, that paragraph disappears.

I'm just thinking loud, trying to understand Drupal, and maybe, suggesting things (from the place of a new newbie user) that will make Drupal a more flexible and friendly... Nobody should be modifying .tpl.php just to get a nice Drupal site... that is very very irritating,
Thanks.

styro’s picture

I cant see the problem here (please, be kind, I'm noobie).

Don't worry, it's ok :)

I mean, lot of information about drupal (example: the path-alias for clean URLs) are stored in the database.

You're slightly misunderstanding what I said. I said "hard coding a theme to a particular database" rather than just storing it in the database. Maybe I should of used the term "tightly coupled to your data" instead of "hard coded to your database".

Currently Drupal has a pretty good (could be better, but much improved over most other CMS tools) separation of concerns. Unless you hack it around a bit, the content (eg the database), the presentation (eg the themes), and the logic (eg modules) aren't that tightly tied together. This is good software design, and it means that module designers and theme designers don't really have to worry about each other much. ie most modules work pretty well on any theme, and vice versa.

A theme designer knows pretty much in advance what classes and ids will be produced by modules, and they code their themes accordingly. They can count on these classes being the same on anybodys Drupal installation. If webmasters could create their own class names or leave some out altogether, then you've just broken the portability of themes, and every site will need to make their own custom theme to match whatever classes are stored in their own database. You've moved from general cases to special cases.

That is what I meant by your solution would be fine for a single site that creates its own custom theme, but it would hurt the community that has built up around creating themes to share. That in turn would raise the barrier for new users unless of course they were happy sticking with the default theme.

I'm also pretty sure that the overhead of extra database queries and PHP processing for all these classes would be higher than the small bandwidth savings you would get by removing them from the HTML.

I'm just thinking loud, trying to understand Drupal, and maybe, suggesting things (from the place of a new newbie user) that will make Drupal a more flexible and friendly... Nobody should be modifying .tpl.php just to get a nice Drupal site... that is very very irritating,

Aha, but how do these extra classes reduce flexibility or friendliness? The users will never know or care about them. And removing them will only reduce flexibility for theme and module designers.

I think this is a case where the solution would be worse than the problem - ie quite a high cost (extra processing, potential for bugs) for very little benefit for a very few users (HTML maybe 4% smaller for a whole lot of effort redefining all your classes). Looking through the HTML source of a Drupal site, I honestly don't think the problem of an extra few scattered class names to be that big of an issue.

If you stick around Drupal longer, and try to use it in a few different scenarios you will start to appreciate some of the design decisions that seemed strange at first.

--
Anton

Nick Lewis’s picture

word!

--
"I'm not concerned about all hell breaking loose, but that a PART of hell will break loose... it'll be much harder to detect." - George Carlin
--
Personal: http://www.nicklewis.org
Work: http://www.zivtech.com

scarecrow-rye’s picture

I have to agree - the ability to assign a class/class-suffix to a specific block would be most welcome.

I'm quite new to Drupal (but have a good background in HTML, CSS and PHP) and am sure that the brains behind the system have already had long discussions about this issue. I haven't yet had the chance to study the Drupal database structure but surely the inclusion of one addition column (class) isn't going to bring the system to a standstill or incur any additional overheads, and would make the life of developers much, much easier.

The ability to include specific, meaningful IDs or class names is core to clean coding, readability and debugging.

gollyg’s picture

All classes, ids and coding structure should be modified at the presentation layer. Your next job in drupal is to look into the theming layer (strongly recommend php template based themes). At this point you can pretty much rewrite the code to suit your site.

By default all blocks do give a specific id and a specific class to their output based upon the module name. The only slightly different case is when you create your own blocks through drupal.

In this case (from memory) the blocks use a delta value as the differentiating factor. Whichever way it is, you can still target blocks specifically from the code that is output. This is controlled in block.tpl.php. A small switch statement or an associative array of preferred id selectors can be added there to control the exact output of your drupal theme.

Other areas of the code can similarly be modified at the theme level.

Adding this stuff to the database adds an unnecessary overhead for every site, not just the one that chooses to use it. It is also a question of if you have just one class, why not two? etc. Not to mention mixing a presentational (mostly) element into the content layer.

I do strongly recommend looking into theming - once you get it you will be able to indulge your desire for clean semantic code ;)

scarecrow-rye’s picture

When creating a new block through the Drupal interface I get something along the lines of...

<div id="block-block-2" class="clear-block block block-block">
<div class="content">
<p><a href="http://www.drupal.org/"><img src="http://cvs.drupal.org/viewcvs/*checkout*/drupal/drupal/misc/powered-blue-135x42.png" width="135" height="42" alt="Powered by Drupal" /></a></p>
</div>

I think I'm right in saying that, when attempting to target a block like this, the only way I can identify it from other blocks created the same way is by targetting its ID, i.e. "block-block-2". Is this correct?

Also, when you say "A small switch statement or an associative array of preferred id selectors can be added there to control the exact output of your drupal theme", do you mean hard-encoding the IDs within the template and swapping them for an alternative CSS selectors?

gollyg’s picture

the id will always give you a unique way to identify the block. In the case you have given this block is being generated by the block module. So the id follows the protoype

  • the fist "block" represents the type of element this is - will always say block for blocks. Basically a namespace to ensure the uniqueness of the id
  • the second part refers to the module that has created the block (in this case it is the block module)
  • the final part is the delta - basically an index for blocks created by the block module

This is generated by

<div class="block block-<?php print $block->module; ?>" id="block-<?php print $block->module; ?>-<?php print $block->delta; ?>"> 

in the bluemarine theme.

As to the second part of your question, yes you can hard code this in the theme. It depends on why you are creating the theme as to whether or not you want to do this. If you are creating it for a specific web site you would probably want this level of control. It doesn't change the functionality of the css and the selectors, just the formatting. If you are developing a generic template for redistribution it is probably better to stick with an established convention.

I normally do a switch statement bases upon the module and delta, and then change the id to something more readable and logical (block-block-3 doesnt really make for easily readable code!)

scarecrow-rye’s picture

Thanks for that.

When it comes to CSS, I've always read that we should give our IDs and classes meaningful names, i.e. "copyright" rather then "block-block-1". So coming to a system where that level of control is lost is a little frustating. Other than that I am very impressed with Drupal so far.

I guess its just a matter of getting my head around a new way of doing things - although it will little my stylesheets with names like "block-block-23" and "block-block-50". No that readable.