Question

I wrote a pretty complicated widget that uses OnDemandList to create a widget that allows full editing (including adding) of a store.

Now... I am not exactly a CSS guru (quite the contrary), and would love some guidance, just to check that I am doings things in a semi-sane way.

When I create the editor in my widget, I do:

buildRendering: function(){ 
    // ... 
    this.domNode = put( 'div' ); 
    // ... 
},   

postCreate: function(){ 
  // ... 
  // This is here, because if I set the class in buildRendering, it gets zapped by className (the widget's declaration) 
  put( this.domNode, '.editable-list' ); 
    // ... 
}, 

Then when an editor is added dynamically:

    put( row.element, editingWidget.domNode ); 
    put( editingWidget.domNode, '.editable-list-row-editor' ); 

I also need to make sure that each row has position:absolute so that the editor gets placed in the right spot:

    domStyle.set( row.element, 'position', 'relative' ); 

In the CSS, I have:

.editable-list-row-editor { 
  position: absolute; 
  top: 0; 
  z-index: 20;
} 

Questions:

1) Is it OK in terms of best practices to even add a style like I did with domStyle.set( row.element, 'position', 'relative' ); ...? Or shall I do that with CSS? I did it programmatically because it's really important that it's relative.

2) Is it OK in terms of CSS to leave things as non-specific as possible? The idea is that users might (and probably will) end up writing their own CSS, and overriding things by writing more specific rules... is that right? Or maybe I should have written:

.editable-list .editable-list-row-editor { 
  position: absolute; 
  top: 0; 
  z-index: 20; 
} 

Or better:

.editable-list .row-editor { 
  position: absolute; 
  top: 0; 
  z-index: 20; 
} 

...?

3) From what I am seeing, CSS classes for widgets should be set in postCreate rather than buildRendering, otherwise Dojo seems to use className to zap anything that was set there... is that what you'd normally do with a widget that creates its own domNode?

Was it helpful?

Solution

My personal opinion on the inline CSS vs CSS stylesheet is that I like to write everything in a seperate stylesheet. The reasoning behind this is that your code becomes cluttered with styling code, but when seperating concerns I think it would be better to write your CSS in a seperate file.

Of course, inline CSS is always the most specific one (the most important one), so if you really want to enforce something, you could add an !important to your CSS rule altought I would recommend use them not that much.


You should write your CSS as specific as possible, because you don't want to interfere with other widgets/HTML but you don't want the opposite as well (external CSS interfering with your widget). But of course, you can write things as:

.editable-list .row-editor {
    position: absolute;
    top: 0;
    z-index: 20;
}

It mostly depends on what .row-editor actually means. If it's something "global", you could keep .row-editor, simply because it will allow you to define a global .row-editor which contains the CSS that is in common, while your .editable-list .row-editor will contain specific CSS rules for that widget.

For example, let's consider that you have another widget with a similar CSS:

.other-widget .row-editor {
    position: absolute;
    top: 0;
    z-index: 25;
}

Then you could also write the following CSS:

.row-editor {
    position: absolute;
    top: 0;
}

.editable-list .row-editor {
    z-index: 20;
}

.other-widget .row-editor {
    z-index: 25;
}

But it actually depends on how you see the .row-editor class, if you think it's only specific to your editable list, then you might also consider prefixing it. It's similar to what Dojo already does, Dojo has global CSS classes like .dijitInline but also specific CSS classes like .dijitCalendarDateLabel.


If someone wants to change the style of the widget, he could add a parent class and so he will be able to make a more specific CSS selector. An example, let's say that the following is your CSS:

.editable-list .row-editor {
    position: absolute;
    top: 0;
    z-index: 20;
}

Then someone who wants to change the CSS just adds a tag to a parent (for example the <body> tag):

<body class="myTheme">
    <!-- Your HTML -->
</body>

And then specifies the following CSS:

.myTheme .editable-list .row-editor {
    z-index: 30;
}

This will actually override your z-index. Dojo already uses this principle with their themes. When you want to use a specific theme, you add the theme CSS and add the name of the theme as a classname in your body, for example:

<body class="claro">
    <!-- Your HTML -->
</body>

Of course you don't need to define it at body-level, as long as it's a parent node of your widget it will work.


About the issue about buildRendering vs postCreate, well, I suppose that you use the dijit/_TemplatedMixin mixin. If that's so, then if you look at the code and look for buildRendering you will see it's doing stuff. This means that if you write your own buildRendering you will actually replace their code with yours. If you want to make sure that Dojo executes its own logic first, you have to write something like:

buildRendering: function() {
    this.inherited(arguments);
    /** Your code */
}

That extra line of code will in fact call the same method of the inherited modules/mixins. You can do with that line what you want, if you don't want that the inherited modules are called, you leave it out (probably breaking it as well), if you want to execute it as the last step you just switch the this.inherited(arguments); to your last step in the buildRendering function (but then it might override your changes).


But in the end, this is all just an opinion and I'm sure that there are other opinions there that are also correct (for other or even similar use cases). But I can tell you that Dojo does things in a similar way for their own widgets, so maybe it's not a bad approach to follow it as well.

Sorry for the long answer, but I wrote it so that it might be useful for similar questions as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top