Pure CSS Submarine

Background

About six years ago I was working with a very mundane data processing program. While looking into some styling for it I researched all the new features being added to CSS e.g. gradients, transitions, and animations. Also, at this time I realized that it was possible to abuse certain aspects of the CSS pseudo-classes. It was then that I had the completely impractical idea of building a submarine game with just CSS. Fortunately in the intervening six years things have greatly improved. For instance I no longer have to deal with browser prefixes.

Over Christmas I suffered some from JS burnout and just took a break from it. The result, I decided to try my hand at mangling CSS.

Here is the completed project. To go down press tab. To go back up press shift+tab. To fire the weapons appropriate at the different levels press the space.  To detonate the weapon press space again (This last part isn’t fully functional see bottom for details). Works best in Firefox and Edge. For some reason Chrome doesn’t show the waves.

Design

Design is pretty easy for this, lots of linear gradients and grey coloring. To get some of the angled edges I at first was going to use the transparent border trick to get triangles, but using gradients on borders was difficult. So, I found and used a technique that used angled linear background gradients.

The sub design was based on this Wikipedia image and various image searches for trident missiles and mk torpedoes.

Techniques

User Interface

The key to the user interface is two invisible inputs

tab and shift+tab toggle back and forth between the two inputs and space allows you to toggle the checked state.

This means you can use :hover and :checked to perform actions on the sub. Also, very key is the ~ sibling selector. This allows any subsequent elements to refer to the state and react accordingly.

Tail

Submarine Tail

The tail presented several interesting challenges. First was the simulation of the spinning propeller.

First the rectangle is skewed to give it the angled tips. Then we scale the div from full height to 0 and back every .3 seconds. Also, as it gets shorter we lighten the color. This makes it look more transparent in the center. The second challenge was adding the vertical fins.

If you’ll notice this gives the triangular tail, but it also colors the outside blue. Meaning layering is an issue and the vertical fins have to sit adjacent to the edges. This can be done by rotating the :before and :after pseudo-elements to the angle of the triangular tail, but we still want an angle on the fin as well.

After rotating the whole element we again add angled linear gradients. First we need the 20deg angle to get the perpendicular grey gradient (20+70=90). Then we add the blue -70deg angle to create a vertical blue strip that creates the left edge. Finally the -160deg angle finishes off the angled top right edge. Mapping this to the bottom fin was actually easy all that was needed was a negative scaling transform to flip what was already created, the supplementary angle of 70 degrees and 55 instead of -55.

Weapons

Adding the torpedo was not complicated. The design was similar to that of the sub itself. The path was pretty easy well. The biggest complication was getting the z-index and layering correct.

The difficulty with the missile was getting a somewhat natural looking trajectory. I found this code that I was able to tweak to get something that looked close.

Sonar

I have to mention something about the sonar. The effect is really simple and I imagine could be useful in actual web pages e.g. showing an active connection.

To begin with use border-radius:50% to get a circular shape. Add a border on the right side so that it looks like it is coming from the nose cone. Then use animation to scale it and make it fade out the large it gets.

The one thing I originally tried was using the pseudo-elements and the parent element, but since the pseudo-element’s position changes based on the parent I scrapped that idea.

Improvements

First thing that could be improved would be using a CSS precompiler like SASS. Not only would it help with a number of the repetitive linear gradients it would allow me to break this up into smaller units. This was one of those projects that you start out just hacking away at and suddenly find it would have been much better to use some type of modularity.

Another big disappointment was the fact that I couldn’t get the weapons to explode. The main problem is when you cancel the animation I want to use an animation to make the weapon disappear and a transition to make the weapon wait for the explosion and then jump back to starting position.

Firefox it works great…the first time. After that it acts like all the other browsers and as soon as you toggle the space bar again the whole element jumps back to the starting position with no pause. Either this is the same bug in every browser or Firefox has a bug by letting it happen the first time.

The problem I addressed in this Stackoverflow question is the fact that when you have an animation it needs a start and end point. If an animation gets canceled in the middle, how do you smoothly transition back to the starting state (Or in my case wait and jump back). A return animation doesn’t work well because you don’t know the starting position. If whatever you are trying to do can be done with transitions to both states then its not a problem. But, if you are trying to create say a torpedo path you can’t just use a transition.

Another thing I couldn’t seem to work around is the the up animation occurring when you load the page and anytime you switch back to it from anything else. Because you have to use an animation for when the input is active and another one for when it isn’t, the sub is always going animate when you switch back to the page and the input receives focus again.

Some other animation improvements would be the path of the missile. I didn’t find many tutorials on creating ballistic trajectories using CSS animations. Also, a more detailed wave animation would be nice, but I wasn’t sure how to tackle that one. Also, since I didn’t get the explosion to happen I didn’t add a shaking animation, but it would be relatively simple to add an element before the sub that contracts and flexes after an explosion to simulate the concussive force. Perhaps possible, but more difficult would be adding splashing water. Related to the weapons would be the trails left by the missile and torpedo, but I didn’t have time see if that was even possible.

Conclusion

I hope you found this interesting if not practical. I have ideas for further abusing CSS pseudo-classes that I may explore in the future. Also some credit is due to several resources I used repeatedly while creating this.

Pure CSS Modal Alert

My previous post was about CSS tooltips. Which after the fact I realized that MDN had a similar tutorial. In this post we will attempt something slightly more complicated – modal alerts.

jsfiddle example

Code

The idea is similar to that of the tooltip. Once you have the alert up use :hover on a full screen pseudo element to keep it there.

In this particular example we are showing an image in the alert.

The key here is to display content on the content hover and on the modal click.

But when we click the content we want to switch to display:none

Advanced Usecase

This next example is still a work in progress, but using these ideas combined with CSS transitions we can do some pretty cool stuff with just CSS.  The idea of this demo is an info button in the corner that has a cool animation when it appears and disappears.

The difficulties of this are dealing with transitions that mean leaving content on the screen that interact poorly with the :hover pseudo class.

I’m sure there are better animations that could be done e.g. something like the minimizing of an application in Windows or Apple. Also, I haven’t quite figured out how to do it with only two elements if anyone finds a clever workaround I’d be interested to know what it is.

Caveats

Again all the caveats from before apply. This is not touch screen friendly. Now it might be possible change using :focus, but that is dependent on if you want to add the complexity.

Another problem is  moving off the browser content will also cancel the alert.

 

Pure CSS Tooltips

CSS Frameworks

One ironic thing about CSS frameworks is many require a JS library to work (And then sometimes they also require Jquery on top of that). One of the things they like to use JS for is tooltips. Which as I’m going to show is not always necessary.

Here is completed jsfiddle example.

Code

Tooltips are actually very easy to do with just CSS. Lets look at an example using tooltips for definitions. Lets say we have a sentence with a word we want to define.

So we have a sentence with a tooltip and a message. All we need now is three CSS rules.

The main trick of this is .tooltip:hover works even when hovering over children. So as soon as you make .message visible as long as the mouse stays on the message it will stay visible.

Improvements

This is a very simple example. Obviously adding shadow effects and possibly some animations would make it more visually appealing. Also, if you wanted to use superscripts similar to Wikipedia. You would need to remove the dotted underline and style accordingly.

A more advanced pure css example Wikipediaesque tooltip.

Caveats

There are several caveats however. First is the lack of support for touch input. This could be added by using links or giving a tabindex and the :active pseudo-class. But this means that clicking on the word will not remove the tooltip until you click somewhere else. So whether this is viable is dependent on the use case.

The second problem is positioning. JS can be used to measure whether the tooltip should be above/below or to the left/right of the target. CSS Doesn’t do a good job of handling this. This may or may not be a problem if used in a central column of text it probably won’t be much of a problem, and if you know for a fact it needs to float another direction you can add a direction class to your tooltip that handles it. The problem is there may be sometime where you don’t know exactly where the target it going to end up in relation to the rest of the page. So again it depends on your use case and on your design.

Why I Chose Javascript Part 2

In part 1 I discussed why I found HTML/CSS so easy to work with. In this article I’ll look at javascript.

Code verbosity

If there was any one thing that stands out as the dividing line between javascript and my previous experience with java it is all the extra typing.

Boilerplate

Compared to

I remember that it took months before I was able to start writing a program without having to check back for a refresher on how to start a program in Java. Javascript was just much simpler to get something up and running.

Imports

Similarly import statements were completely mystifying.

Sure the more general import helped, but only if you knew how that worked. Combine that with the fact that that both of the below are necessary because awt.event is a completely separate package from awt. All of this is a sure way to make a beginner give up.

Initializing Objects

I think this is pretty self-explanatory.

Extra typing comes at a cost

You might point out that its just a little extra typing. But part of the problem is the added complexity, especially for someone starting out. Understanding why you need public static void main is a problem and if you are taking a course they just tell you to accept it and move on. The same is true of objects not only did it feel incredibly redundant to type out <String> twice. I had no clue what most of the syntax was doing which made it even harder to remember it accurately.

I’m not saying that javascript doesn’t at times feel awkward or redundant, but as a whole it was easier to type the code. Which also meant that when there was an error it was less likely to be in some part of boilerplate that I mistyped because I didn’t know what it was in the first place.

Types

This is more of a general point on the difference between compiled versus scripting languages. In javascript except for 6 distinct primitives everything is an object. Java for instance has 10 types of numbers. Which is great if you are writing something that depends on the performance and memory difference between using a byte and int, but many applications don’t need the that level of optimization.

I don’t want to repeat the hundreds of articles out there arguing for or against static types. But I know personally var was easier to code with because again less complexity made it easier for me to focus on the problem I was trying to solve.

Some final thoughts

Ironically I didn’t really understand objects and OOP until after I started using prototypal inheritance in javascript. One day when working with javascript object it just clicked how OOP was supposed to work. In Java I tended to get so bogged down in syntax that it I never quite got a good grasp of what the whole point was.

Another pain point was when trying to work with regex and strings. Java’s implementation is  more complicated. I wrote a program centering around string manipulation in both javascript and java. Java’s was limited and error prone whereas the one written in javascript was easier to develop and much more stable.

One key thing is the accessibility of developing in the browser. I found it so easy to get up and running. Related to that is the amount of information on the web. Not everything on the web is of the same quality, but there were tutorials, code examples, and articles in abundance. Which is great because almost any problem you run into someone has written something about it.

Finally I’m not saying that Java has no place. What I am saying is especially for someone new to programming javascript presents a lot fewer barriers to entry. Add to this the fact that the power behind languages like Java and C++ is overkill for many programs being written today. Personally despite its quirks I have come to enjoy programming in javascript. I’m not sure I ever was going to be able to say that about Java.

Why I Chose Javascript Part 1

As discussed in my about page I really started programming in Java, but I later switched to javascript. There were two primary reasons for this. This article is about the first.

User interfaces

Ironically this is not about the relative strengths/weaknesses of java versus javascript, but on the ease of design with HTML and CSS. I’m pretty sure everyone who learned to program and enjoyed it wanted to create something that people could use. I was no different, but while I could construct a program my interface options were command line, manipulating files with predefined names or clunky painful to code (probably to use as well) GUIs created in NetBeans.

Now some of this was just a lack of knowledge and skill on my part, but as a beginner to programming the goal of creating an application usable by nontechnical people seemed hopelessly out of  reach. Until I started using HTML/CSS. I was almost immediately hooked. For all the browser quirks and DOM idiosyncrasies I found it so easy to take an idea and start seeing results immediately. This was combined with benefit of not needing a special program to help me build a UI. I could open Notepad and a browser and create something that didn’t need build steps or dependencies.

Distribution

Another problem I quickly ran into was trying to distribute .jar files. It is one thing for something to work on your computer, but getting it to work on another computer was a whole problem in and of itself, not to mention issuing updates. Different OSs, Java versions or no Java at all was a headache. Some of this I will cover in part 2, but the big thing is the browser was universal and easy to target on multiple platforms. There is the giant caveat that was IE6, but even then for the most part the basics of HTML and CSS worked on all platforms.

I remember having a conversation with a friend about this, and one of the things I said was I wished that they had methods to build a UI that were as simple as HTML/CSS. I’m sure that there were/are simpler methods, but while I was too new to recognize or understand the concept of separation of concerns I appreciated the simplicity of it.

Fast forward a number of years and now I am no longer a novice at programming. During that time I found that CSS did have some pain points and HTML does have some limitations, but I still feel that HTML/CSS is great for beginners and still flexible enough for advanced uses such as SPA. Of course many advanced UIs use some kind of virtual DOM, while this does blur the line between code and content. Many implementations of virtual DOM have syntax that looks similar to HTML.

In part 2 I’ll look at why javascript made sense to me.

Hello World

Welcome to my blog where I hope to discuss my interest in web design and programming in general. I hope to post once a week. Also, at some point I want to finish building a custom theme, but for now you are stuck with this standard one.