7

Frustrated by the many limitations and compatibility issues of CSS, and finding myself constantly needing to write javascript code to get my webpages to layout the way I wanted, I thought I might be able streamline future projects by ditching CSS altogether for page structuring.

I wrote a javascript library which parses layouts specified in XML files, and applies them to an HTML document using absolutely positioned and sized, non-nested divs. So the idea is that each page has an HTML file containing all content, an XML file specifying how that content should be arranged on the page, and a CSS style sheet for superficial styling.

Here is an example. (press the button to inflate the layout. tested in latest version of all major browsers.) And another.

This system degrades gracefully to plain html, and even allows for separate styling in the case that javascript is disabled.

It seems to me that this approach not only eliminates many cross-browser issues, but also allows me to achieve more complex layouts with less work. For example, my understanding is that the following cannot be done with CSS alone, at least not without a mess of nested divs:

  1. Set an element to fill available width or height within its parent container. (This is not the same as width/height:100% if there are other elements in the parent container.)
  2. Align any element top/center/bottom, left/center/right within any container, even if its size is unknown.
  3. Pad an element of unknown size, without increasing that elements size (For example, if a div is set to 100% of the window size, it cannot be padded without overflowing the window.)
  4. Automatically set all elements within a parent element to be equally spaced apart.
  5. Set the height of a floating element. Similarly, independently set shrink-wrapping behavior horizontally and vertically.
  6. Set elements to float in columns rather than rows (CSS3 seems to support columns but browser compatibility is not good)

Nonetheless, I'm sure this is considered blasphemous. So, what are the potential problems with using this system to layout web pages?

EDIT: the code is on github

Madison Brown
  • 331
  • 3
  • 10
  • I imagine it will be slow when the page gets big and complex. But I understand your frustrations regarding limitation in CSS. Keep us updated on the development of your library. – Lian Jun 20 '13 at 18:31
  • so far, i've done some rather large tests and speed hasn't been a problem. then again, i have a pretty fast processor. but on my computer, it holds up even when constantly resizing the window. – Madison Brown Jun 20 '13 at 18:33
  • 1
    Most annoying thing for me would be having to handle simple style changes such as :hover with far more complicated JavaScript. Interesting idea though – Turnip Jun 20 '13 at 18:36
  • I tried it in IE8 and all I see is a green square. – Lian Jun 20 '13 at 18:39
  • well this doesn't really change how superficial styling is achieved. for example if you just want to change the color of a div onmouseover, that could still be done use css alone. at the moment, you wouldn't be able to change the size onmouseover, but i imagine support for that could be implemented pretty easily. – Madison Brown Jun 20 '13 at 18:41
  • @Lian i haven't tested it in old browsers yet, ill look into that – Madison Brown Jun 20 '13 at 18:44
  • I am not criticizing the approach, but would like to know your thinking if the user doesn't have javascript enabled for some reasons. – Sunny Jun 20 '13 at 18:45
  • 2
    Well, I think for all these problems there are CSS3 features (with differing browser support of course)… – Bergi Jun 20 '13 at 18:45
  • @sunny as i mentioned, if javascript is not enabled, the layout won't inflate and the user gets the plain html version (which should be laid out in logical order). separate styling could be applied to this if you wanted – Madison Brown Jun 20 '13 at 18:49
  • @Bergi are you sure ALL of the problems have CSS3 solutions? i'd be interested to see your solutions. – Madison Brown Jun 20 '13 at 18:49
  • Oh sorry, I missed that – Sunny Jun 20 '13 at 18:50
  • Most of these are a lot easier to accomplish with `box-sizing:border-box;` – landons Jun 20 '13 at 18:50
  • @landons uhh.. i see that number 3 can be accomplished with box-sizing, but what about the other 5? – Madison Brown Jun 20 '13 at 18:54
  • @MadisonBrown It would help significantly with #4, but any CSS fluid CSS layouts, really. – landons Jun 20 '13 at 18:56
  • @landons nevertheless, there are still plenty of limitations, and no one can deny that cross-browser support of css is a waste of time to deal with. furthermore, css will always be behind-the-times. it seems helpful to me to have control over exactly how my content is rendered client-side, regardless of browser or version. the library is still in the early stages right now, but I can implement any features i imagine – Madison Brown Jun 20 '13 at 19:01
  • @MadisonBrown I politely disagree. CSS has far better cross-browser support than it did when I started 10 years ago. Javascript-based layouts would IMO be harder to implement consistently. – landons Jun 20 '13 at 19:03
  • @Madison: You already encountered `box-sizing` from [CSS3 UI](http://www.w3.org/TR/css3-ui/) and [columns](http://www.w3.org/TR/css3-multicol/). You mostly will be interested in [flex-box](http://www.w3.org/TR/css3-flexbox/) (#2, #4). Not sure though what you exactly mean with #1 and #5. "fill available space" is the default rule of all layout engines :-) – Bergi Jun 20 '13 at 19:15
  • @Bergi fill available space means if i have a parent container of width 500px with two children floating left, one child with an absolute width of 100px and the other with a width set to fill, then the fill child will take up 400px width. – Madison Brown Jun 20 '13 at 19:23
  • @MadisonBrown The fill child should have `overflow:hidden` – landons Jun 20 '13 at 20:08
  • @Bergi but what if the fill child contains text? Solutions in CSS always seem like hacks or workarounds... – Madison Brown Jun 20 '13 at 20:10
  • @Madison: Ah OK. I'd use `.container { position:relative } .left { position:absolute; left:0; width: 100px } .right { position:absolute; left:100px; right:0 }` but you're right it's ugly. Again, `flex-box` will take care of exactly this usecase :-) – Bergi Jun 20 '13 at 21:07
  • if someone can recreate my example such that it maintains complete separation of style and content, uses no javascript, AND works in any browser (including the stock browser on my android phone) then i'll be convinced of the power of CSS that I am apparently missing. even if it can be done, I guarantee the CSS will be an ugly mess. – Madison Brown Jun 21 '13 at 00:36

4 Answers4

4

You are, essentially, trying to rewrite CSS, in a way that you feel does the job better than CSS. This can be fine -- maybe it works for you -- but you will face limitations.

The rest of the world uses CSS. It is usually easier to get one person (you) to learn and follow a standard than to try to get the rest of the world to learn and follow your standard. If you develop with anyone else, instead of being able to bring their knowledge of CSS and HTML to the table, they'll have to learn your method of web development.

If you go to work elsewhere, you'll either have to convince them to be able to bring your method to the table, rather than use the world standard of CSS (this generally doesn't fly in the corporate environment), or you'll have to then learn how to use CSS properly.

If you look to get help from anyone else (such as here on stackoverflow), you won't be able to, since everyone else uses CSS. But if you have issues with CSS, we'll be able to help.

That is why it might be considered "blasphemous". I'm sure you wrote this question intending to receive feedback on the potential technical problems with that approach, but I think the political/community problems are just as important.

droozen
  • 176
  • 4
  • some good points! I am aware that it would be difficult to get others to make a change like this. But i'm not actually intending to never use CSS again, I made this as more of an interesting experiment, and if it can save me some time in the future, all the better! – Madison Brown Jun 20 '13 at 19:19
3

You have invented a more powerful system for laying out pages. You should note that CSS already has draft specifications of other such systems:

Here is a January 2013 overview of these proposals, the followup to a 2011 overview.

These specifications are only drafts. Some of them will probably end up being be scrapped or merged with other specs. A few browsers already implement portions of these specs, usually behind vendor prefixes.

Though you can't reliably use these features in your CSS today, you should consider these specs' designs when writing your library. You should copy the parts of their designs that offer powerful layout tools, or that are clean and future-proof.

It may even be best to, instead of writing your own JavaScript library and XML syntax, just use existing JavaScript polyfills, such as these (not an exhaustive list):

You would use polyfills like these in conjunction with CSS using the draft's syntax.

Even if these polyfills are not full-featured or stable enough to use, you might be able to call them from your library, or at least copy some of their code.

Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
  • thanks for the suggestions, I will look into them. that's the main problem with css... even when the specs are good in theory, it still turns into a huge mess when 5+ browsers all try to implement them separately. – Madison Brown Jun 20 '13 at 20:18
  • not to mention trying to get things to work on mobile devices! – Madison Brown Jun 20 '13 at 20:29
1

"Frustrated by the many limitations and compatibility issues of CSS, and finding myself constantly needing to write javascript code to get my webpages to layout the way I wanted" suggests you've either been using CSS wrong, or have not actually put in enough time learning the ins and outs of CSS to make it do what you want (setting up good, universal CSS is hard, -just like programming JS- and there are a million ways to do it wrong - just like programming JS).

Your example seems to work based on a 100% height page. This is actually relatively easy once you set html and body to height:100% for instance. Once you do that, h/valigning of boxes becomes really easy.

Then, in answer to your question: doing all your styling using JS calls will be much more expensive than using CSS, so I strongly suspect your solution will perform far worse than a good CSS, or CSS+JS, solution. Browsers have extremely optimised code for performing CSS-triggered reflows, and doing the same thing in JavaScript is several times slower. Using JS for specific styling because CSS is lacking a feature, like doing box aligning like your example, is usually a necessity, but everytime you run it, it'll have to rerun the full algorithm in JS code, rather than using the native compiler much-faster reflow libraries that might available for some -or all- of the layout you want to achieve.

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • the example uses height 100%, but it could be set to anything. yes, i am aware that my approach is more expensive, but the difference in rendering time is not perceptible to a human, so im not sure its a real problem. – Madison Brown Jun 20 '13 at 19:10
  • 1
    Unless you're using an old computer to test this one, that's not really an argument the real world is going to accept =) – Mike 'Pomax' Kamermans Jun 20 '13 at 19:17
  • 1
    more expensive != worse unless you're actually having performance issues – Josh Noe Jun 20 '13 at 19:18
0

I see no problems with this, apart from the fact that you'll have to ensure identical output for all browsers you choose to support. Additionally, you'll have to deal with situations where the amount of elements on the page is a variable, like a photo gallery or comment page. I can tell you from experience that lots of small elements positioned absolutely will severely degrade the performance of the page. You'll notice this when scrolling and resizing the window when you reach 50-100 elements. Instead, do what Google Images does in this situation; set the elements to display: inline-block and control their widths, then allow them to wrap naturally.

Also I feel I should point out that point #1 and #2 can be easily be done in CSS by using position: relative on the parent and position: absolute on the children, and point #3 can be solved by setting box-sizing: border-box on the child. You could use padding-box but that's not as well supported.

Several of your concerns is also being addressed in CSS3. You mentioned CSS3 columns. Take a look at calc as well. For instance, you'll be able to do this to centre an element with a dynamic size:

left: 50%;
top: 50%;
margin-left: calc(-width / 2)
margin-top: calc(-height / 2)
Hubro
  • 56,214
  • 69
  • 228
  • 381
  • the system is inherently cross-browser because it only uses position absolute and width/height in pixels. As far as i am aware every browser implements those aspects of css the same. And it's really only meant to handle the basic structuring of the page, individual elements like a photo gallery could by styled by css if it was deemed appropriate in that case. Also, scrolling does not require any recalculations. – Madison Brown Jun 20 '13 at 19:15