How to create triangles using CSS easily

We often see some tooltips that uses triangular arrows to emphasize the content and images were often used for the arrows. Now, with new techniques, we can create these arrows in CSS just fine.

Here’s an example:

CSS equilateral triangle


We’ll use CSS borders to create the triangles. You may ask, “Why can borders do that?”. It’s because browsers draw borders as triangles and we can use that to make triangles.

First, as the borders are drawn around the container we need to make sure the container has no width & height (i.e. set them to zeros).


<div id="triangle"></div>


#triangle {
    width: 0;
    height: 0;

Then, we need to add borders in. In order to aid the creation of triangles, we need to add colours to all sides. It’ll now look like this:

Triangles diagram



#triangle {
    border-top: red 2em solid;
    border-bottom: green 2em solid;
    border-left: blue 2em solid;
    border-right: orange 2em solid;

You can now see 4 triangles showing up. By adjusting the thickness of each side of border, you can create different types and sizes of triangles. Examples are:

Triangles example 3Triangles example 2Triangles examples 1

After that, you need to eliminate the other parts by setting their colour to transparent. Now it’s finished just like the first diagram. You can even make dialogues using this technique with CSS3’s :before & :after selectors. It’s very cool, isn’t it?

Here’s some things that I’ve made with this technique. Check it out!

What I think about DV tape readers


DV tape reader, because of digitalization, it has already faded out from many filmakers’ eyes. I also forget this little device for quite a long time.

Before I found this thingy again, I needed to get the video from some DV tapes. That IS almost the most annoying thing in the world!!! That is the longest process before any recording. Besides that, that thingy may have potential errors and the whole capture has to be repeated, again.

The capture speed of DV tape readers goes up linearly which means that the longer the video, the longer to capture.

After I got a nice digital camcorder, I actually don’t need this thing anymore but I still have a need to read these tapes. Surprisingly, I don’t see any errors when playing tapes. That is totally different than what I had experienced before: it isn’t really that bad.

To conclude: DV tapes readers are starting to fade out from people’s memory, but it still have the need to exist .

GLSL fragment shaders in JavaScript!

Recent I see some very nice visual effects done in GLSL fragment shader here. I love them very much and I started learning GLSL fragment shaders afterwards.

I think that they are great but they must run on GPU. Only some browser vendors provide API to access the GPU (Actually, that API is called WebGL) so these visuals can’t run on some browsers that don’t offer the WebGL API.

In order to overcome these, I tried to port GLSL fragment shaders to javascript and draw the result using HTML5 canvas. The canvas API has a much broader browser support (and a flash fallback is available).

The demos I created are un-optimized and maybe a bit slow. After all, GLSL shaders are supposed to run on a GPU. However, it’s still worth to convert some of the GLSL shaders to achieve some nice effect such as post-processing of photos.

Here’s the demo:


The techniques I used is to render the pixels one by one, with the render function be the one in the GLSL fragment shader. Also, we need to change the schematics (vec2, vec3, etc.) to its JavaScript equivalent.

Here’s the format of the code:

//The requestAnimFrame fallback for better and smoother animation
window.requestAnimFrame = (function () {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
        window.setTimeout(callback, 1000 / 60);

//Prepare our canvas
var canvas = document.querySelector('#render');
var w = window.innerWidth;
var h = window.innerHeight;
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');

var time =;
var buffer = ctx.createImageData(w, h);//The back buffer we used to paint the result into the canvas

//The main rencer function
function render(time, fragcoord) {
    /* put the GLSL fragment shader's JavaScript equivalent here. */
    return [0,0,0,0]; //the final colour value

function animate() {
    var delta = ( - time) / 1000;
    buffer = ctx.createImageData(w, h);
    ctx.clearRect(0, 0, w, h);
    for (var x = 0; x < w; x++) {
        for (var y = 0; y < h; y++) {
            var ret = render(delta, [x, y]);
            var i = (y * buffer.width + x) * 4;
  [i] = ret[0] * 255;
  [i + 1] = ret[1] * 255;
  [i + 2] = ret[2] * 255;
  [i + 3] = ret[3] * 255;
    ctx.putImageData(buffer, 0, 0);

window.onresize = function () {
    w = window.innerWidth;
    h = window.innerHeight;
    canvas.width = w;
    canvas.height = h;


Hope you like it and encouraged you to start learning about computer graphics.

Brackets – A nice, lightweight code editor for the web by Adobe

Before this, I used Dreamweaver to code. However, I found the CPU usage rises a lot when I use it and it costs me a few hundred megabytes to install. After that, I started to find other code editors that is lightweight and powerful. Finally, Brackets is the one that satisfies my needs so I recommend it to you. Below is some information that I quoted from their websites:

About Brackets

Brackets is an open-source editor for web design and development built on top of web technologies such as HTML, CSS and JavaScript. The project was created and is maintained by Adobe, and is released under an MIT License.

Guiding Ideas


Brackets is built using HTML, CSS and JavaScript. If you can code in Brackets, you can code on Brackets.


Brackets, is a fully open-source, community-driven project. Want to influence its direction? Join the developer list and start contributing.


Rather than clutter your workspace with floating panels, toolbars and icons, Brackets focuses on providing “Quick Edit” in-line views that provide context-sensitive access to your content, without taking you away from your code.


The browser is your design view. Brackets hooks up directly to the browser, allowing you to design and develop in the same environment that you deploy.

Download it here.

My latest survey service – PollEndpoint

I created PollEndpoint originally for my homework assignment because other online survey service doesn’t match my requirements. So I made my own site for making online questionnaires and I found it pretty useful for others so I release it.

It is made with node.js which is pretty fast and stable (it’s been proven by Microsoft). It also has an easy-to-use step-by-step interface to create polls. It also has a nice real-time statistics which is easy to read. (Somehow I feel like advertising my product.)

It has some features that is, unique from other online questionnaire services. Examples are:

  1. Responsive design that fits your screen even if you’re using a mobile phone.
  2. Uses HTML5 Microdata and other tags to increase the view rate and achieve better SEO.
  3. PollEndpoint can be embedded to other webpages/blogs through the embed code.
  4. It contains no ads!

By the way, here’s a demo of the embed code.

<iframe width="100%" height="400" style="overflow: hidden;" src=""></iframe>

My latest experiment – audio distortion with the Web Audio API

Recently I’ve created a brand new experiment – audio distortion using the Web Audio API. It works great.

Experiment Here

You may ask: why I have the idea of doing audio distortion on the web?

It’s because I think that distorting audio gives us an effect of old, weird cassette tapes sounds and makes the audio a bit of vintage feel. (I love vintage things so much 🙂 )

Remember, Web Audio API is currently only available on Chrome and Safari 6 so please use them to visit my experiment or that’s your problem.

Isn’t this post too short? Yeah it surely is. Remember to see my other posts!