X11: Almost a GUI
X11 is a mechanism for displaying pixels on a screen. Beyond that, it supports some very basic windowing abilities. If you want to display things such as buttons and scrollbars, you need a higher-level toolkit.
In itself, this isn't a bad idea. Adding extra layers of abstraction incurs a slight performance penalty, but makes code a lot more maintainable. The first problem is that there is no standard toolkit—or rather, there are several, so it's very difficult for applications to have the same basic look and feel. Of course, the lack of a set of published human interface guidelines for X11 doesn't really help, either.
The main problem with X11 is network transparency. One of the design requirements for X11 was that it would allow remote display. Unfortunately, this is at much too low a level. All X11 does is remote display—all of the logic remains at the opposite end of the connection from the display. If you're on a fast local connection, this distinction doesn't matter much. If you're on the other end of a slow or high-latency connection, however, it really does matter.
At the same time X11 was becoming popular, another system was developed. NeWS was based on PostScript. The most obvious advantage of this origin for developers was that you could send the same PostScript output to the screen as to a printer. The second advantage was that it ran UI components on the machine connected to the screen. If you pressed a button, enough logic would be available locally to respond to the button press and send an event to the server.
On the X11 model, the click is sent to the machine running the application, which then must send each frame in the sequence of actions to the screen. If this seems bad, consider a text field—every time you enter a character, it requires a round trip to the server to display it. Now imagine that you're on an Internet link with a 200ms latency to the server.
The idea behind NeWS was so good that it keeps being reinvented. The latest Internet buzzword, AJAX, is another implementation of the same concept. User interface elements are rendered by a browser, and the back-end server asynchronously provides the application logic. Even before that, Java applets were doing the same thing—drawing the UI in Java and communicating with a remote server running the rest of the application.