Why and how to create Microsoft Office Minibar with jQuery and CSS3

Although many will argue that Microsoft products are an example of a good design, Minibar was one of design refreshments that came out with the Office 2007. It is a variation of a toolbar that exposes context-related functionality. In case of MS Word, context is a text selection. Since Minibar always pops up near the mouse pointer it enables users to quickly perform actions related to a selection.

Check out demo

So how it works? When user makes a selection in input field Minibar pops up, semi-transparent, above the selection. When user hovers the Minibar it fades out. It disappears when user clicks anywhere in the input field or performs an action by clicking on a Minibar button.

Quite simple Minibar will be shown in this tutorial - it has only bold, underline, italic, and link buttons.

<textarea id="description" rows="8" cols="50"></textarea>
<div id="menu">
    <a href="#" id="bold">b</a>
    <a href="#" id="italic">i</a>
    <a href="#" id="underline">u</a>
    <a href="#" id="link">Link</a>
</div>

We need to make Minibar semi-transparent initially, and solid-color on hover.

#menu {padding:5px; background-color:#f5f5f5;
background-color:rgba(245, 245, 245, 0.6);        display:none; position:absolute; top:0px; left:0px; overflow:hidden;        border:solid 1px #929292; border-radius:3px; -moz-border-radius:3px;        -webit-border-radius:3px; box-shadow: 5px 5px 5px #888;        -moz-box-shadow: 1px 1px 3px #555; -webkit-box-shadow: 5px 5px 5px #888;} #menu:hover {background-color:rgba(245, 245, 245, 1);}

Fade it in and out

To be able to control Minibar position we will need to track the mouse position and use x an y coordinate to set top and left properties of its container. To show Minibar upon selection we will use .select() event, where its container will be faded in at the specific location. We also need to handle .mousedown() event in order to fade the Minibar out when user click somewhere else.

$(document).ready(function() {
    var mouseX = 0;
    var mouseY = 0;

    $("#description").mousemove(function(e) {
        // track mouse position
        mouseX = e.pageX;
        mouseY = e.pageY;
    });
   
    // Fade out the menu on any click
    $("#description").mousedown(function() {
        $("#menu").fadeOut("1000");
    });

    $("#description").select(function() {
        // get the mouse position an show the menu
        $("#menu").css("top", mouseY - 30)
            .css("left", mouseX + 10).fadeIn("1000");
    });
});

Handling clicks

Now when we know how to handle fading in and out, we can add some functionality. If we want to make a selection bold, we can wrap it with <strong> and </strong> tags (of course, it can be done with span element and some CSS but for the purpose of this tutorial I will wrap selection with tags).

function wrapText(startText, endText){
    // Get the text before the selection
    var before = $("#description").val().substring(0, $("#description").caret().start);
   
    // Get the text after the selection
    var after = $("#description").val().substring($("#description").caret().end, $("#description").val().length);
   
    // merge text before the selection, a selection wrapped with inserted text and a text after the selection
    $("#description").val(before + startText + $("#description").caret().text + endText + after);
}

This function, which relies on jCaret plugin wraps the selection with tags and merge it with text before and after the selection. Quite simple, when you have useful plugin such as jCaret. We only need to handle click events for each Minibar button.

$("#bold").click(function() {
    wrapText("<strong>", "</strong>");
    $("#menu").fadeOut("1000");
});

$("#italic").click(function() {
    wrapText("<em>", "</em>");
    $("#menu").fadeOut("1000");
});

$("#underline").click(function() {
    wrapText("<u>", "</u>");
    $("#menu").fadeOut("1000");
});

$("#link").click(function() {
    var url = prompt("Enter URL", "http://");
    if (url != null)
        wrapText("<a href='" + url + "'>", "</a>");
    $("#menu").fadeOut("1000");
});

Handling click events for bold, italic and underline actions is more than simple. We just call wrapText() function, pass it appropriate start and end tags and fade Minibar out. Handling click for link button is a bit different - we first need to prompt users to enter URL and then pass the URL inside opening tag.

Check out demo

Conclusion

As a regular Word user I am so used to this small toolbar and I am missing it on the web. I would really like to see it as a feature in WYSIWYG editors such as TinyMCE. It can also be a part of comment/contact forms. In order to play around with it more I will add it to my comment form as a part of the current blog realign.

Although it works in all major browsers, the code is everything but perfect - it can be optimized and more features can be seen here. Feel free to play with it and if you find any bug, please drop me a line.

More articles in Blog archive or elsewhere
Advertisement

53 Comment(s)

Diogo

Diogo 24 May 2010 #

One of the most useful tips/posts ever! Laughing
This would be great if implemented in forums, blogs, etc

MauxWebmaster

MauxWebmaster 24 May 2010 #

Great post!
Incredible!
Very useful!

Mike Stokes

Mike Stokes 24 May 2010 #

Janko - I love it!  It's so much less obtrusive than a toolbar that is always up.  It makes for a much cleaner writing space which I really like as it keeps the creativity focused on what's important... which for an easily distracted person like me is important Smile

Janko

Janko 24 May 2010 #

Yeah, it's a nice tool to have, I don't know why it isn't supported by wysiwyg editors so far.

Saurabh Shah

Saurabh Shah 24 May 2010 #

This is an amazing tutorial.  For sure very handly to use it. Thanks for sharing it.

Ahmad Alfy

Ahmad Alfy 24 May 2010 #

Great concept! Would be great if implemented on WYSIWYG editors like TinyMCE!
Just one note, I think you should replace <b> and <i> with <strong> and <em>!
I am sure you're already aware of this Smile

Janko

Janko 24 May 2010 #

Thanks Ahmad, fixed!

Manmohanjit Singh

Manmohanjit Singh 24 May 2010 #

Good stuff. Nice job with the CSS3 Smile

Jonatan Lundin

Jonatan Lundin 24 May 2010 #

Really interesting idea. Having a "minibar" together with a contentEditable based WYSIWYG- or WYSIWYM-editor would make front end/inline editing of rich content work like a charm! No more pop-ups or clunky editors appearing out of nowhere when you edit content.

This is definitely something I'll consider adding to the road map for future versions of WYMeditor.

Janko

Janko 26 May 2010 #

WYMeditor looks nice, it would be good to see how would minibar work with it.

amantur

amantur 24 May 2010 #

this is amazing!

sivaranjan

sivaranjan 24 May 2010 #


Your website is incredibly beautiful and useful. I have taken liberty to add this article to my CSS aggregator site. I hope you wont mind that.

Janko

Janko 26 May 2010 #

Anytime Smile

sojan

sojan 24 May 2010 #

reallyy a great post Smile

Brian Boatright

Brian Boatright 24 May 2010 #

This is a great article and demo. Thanks!

wespai

wespai 25 May 2010 #

nice plugin

Scott Corgan

Scott Corgan 25 May 2010 #

Ohh, put it in Wordpress!!

enam

enam 25 May 2010 #

very nice post. Thanks a lot.

Marco

Marco 25 May 2010 #

Well done Janko, another great example of an application (part) ported to the web. Although I don't like/use the minibar at all in Word, I know other people might like it.

Keep up the great work mate!

Janko

Janko 26 May 2010 #

I'm glad you like it. It would be really helpful to have it while writing articles Smile

Arun Prasad

Arun Prasad 25 May 2010 #

Wow!  I really love jQuery and css3. Great post Janko. I enjoyed reading it. I'm going to implement this in an application that I'm working with.

Thank you so much for sharing this.

Webstandard-Blog

Webstandard-Blog 25 May 2010 #

Awesome Janko, very nice solution! Thx for sharing it!

Pau Codina

Pau Codina 25 May 2010 #

Wow!! very useful and creative!

Barbara Laird

Barbara Laird 25 May 2010 #

Nice!  I think I'll add it to my Wordpress comment form.

Aur&#233;

Auré 26 May 2010 #

Waho... great Smile
I will try to add this to my blog comment form.
Thanks for sharing dude ;)

Janko

Janko 26 May 2010 #

Thanks Auré! Btw, you have really fantastic site.

Aur&#233;

Auré 26 May 2010 #

Thanks a lot I appreciate the compliment dude Smile (it's not the definitive version yet I'm optimizing again and again)

Bubu

Bubu 26 May 2010 #

Hi all.

Great job Janko ! Very usefull !
It could be really awsome to have the color gestion (texts and text-backgrounds) ! lol Smile

Bye, cool !

Bubu

Bubu 26 May 2010 #

I just wanted to add for those who would insert your plugin into a forum, that they have to take care of the real HTML tags you decided to use because hackers could be tempted to write some bad codes you'd insert in a database for example and which would be executed later when you load it orsome other bad things ...
That why all forum use [quote] [bold] etc etc because you don't have to worry about that. When you read your database, you just use a "strtr()" or "preg_replace()" and that's all ;)

(sorry for my english :p)

Kevin

Kevin 28 May 2010 #

IE6 has issues with demo (just transparency) needs a background color it seems for ie6. Other than that this rocks

Janko

Janko 28 May 2010 #

I don't test my work in IE6 anymore, I don't even know how my site ugly is in ie6 ;)

SJL Web Design

SJL Web Design 28 May 2010 #

Great post and code, this is really useful!!

Thanks.

Bernardo

Bernardo 28 May 2010 #

just beautiful!!!

Txs.

Andy

Andy 28 May 2010 #

Don't you mean:
"Although many will argue that Microsoft products *aren't* an example of good design..."

?

Janko

Janko 28 May 2010 #

Exactly. I missed that.

Mark Freeman

Mark Freeman 28 May 2010 #

This would be great for wikis too. And the comment input field of blog pages like this one. Smile

Janko

Janko 28 May 2010 #

Wikis are exactly the types of site where this can be useful, inline edits as well.

SyntaX

SyntaX 28 May 2010 #

How can I install that in Wordpress? Pls. Help!

Theo

Theo 31 May 2010 #

Great idea and article, very useful and well written tutorial. Thanks for sharing!

Mike Helton

Mike Helton 31 May 2010 #

I like the idea.

What I really like is more writing and viewing space.

Is this available for using in wordpress or a platform similar to that?

Good post,
Mike

Igor

Igor 20 Jun 2010 #

Check this approach - http://mini.squiz.net/features/inline-editing
Way cooler than anything else.

Diego

Diego 23 Jun 2010 #

Nice idea, the only issue is that CSS should be tweaked a little, as it doesn't work properly on IE. The cause is the ":hover", which, on IE, is supported only on <a> elements.

AIK

AIK 26 Jul 2010 #

Very nice article, UI concepts, code.  The only issue: DON'T use HTML as your source data.  To see why: in your demo, try to enter <form> ... some hacking stuff, like <input type=submit value=submit name=submit> ... </form> and then change some arbitrary tag to bold, for example.

This issue is common for all WYSIWYG HTML editors.  A nice solution: use a different mark-up (e.g., Textile).

Azeem Michael

Azeem Michael 28 Sep 2010 #

nice work. thanks!

Chris Wheeler

Chris Wheeler 09 Oct 2010 #

This is one of the best I have seen from you Janko. Keep up the good work and feed us some more quick!

Jeff

Jeff 12 Oct 2010 #

Thanks for this. I found it through a link from Smashing Magazine and it's perfect for what I need.

Anybody have any thoughts on how to implement this for MULTIPLE text boxes on the page without having to duplicate a lot of code?

Edgar

Edgar 13 Oct 2010 #

That's a great article,
i just want to know if there is a way to make an undo to any change made with this minibar.

Regards,

Scott Richardson

Scott Richardson 14 Oct 2010 #

Any reason why when I select text in my form textarea, the popup tools appear too far to the right? Almost as if it's not tracking the mouse coordinates properly?

Janko

Janko 14 Oct 2010 #

Hey Scott, which browser/OS you use? Seems to be working fine in browsers I tested, but there's always a room for mistake Smile

Scott Richardson

Scott Richardson 15 Oct 2010 #

OK so it turns out that if your form elements are inside a div that has relative positioning in it, it breaks the popup positioning. Any way to fix this without putting the #menu outside the relative div?

Scott

Adam

Adam 23 Oct 2010 #

This is a really great article Janko, thanks for sharing this and thanks for the code this will come in very useful!

matt

matt 18 Nov 2010 #

nice work, just stinks that when you re-highlight your text, you cannot remove the styles applied.

Philipp

Philipp 19 Nov 2010 #

to remove styles you could add an extra button with an extra function, something like this

$("#button").click(function(){
  var markup = $("#text").val();
  var markup = markup.replace(/<\/?[^>]+(>|$)/g, "");
  $("#text").val(markup);
  $("#preview").val(markup);
}

this function removes all html elements

another problem are linebreaks:
make some breaks in the textfield and mark a word after the linebreaks and try to edit it, in firefox everything is great but in ie it isnt, its counting the wrong number of letters before and after the marked word

i wonder if there is a better solution than counting the linebreaks and edit the selection

Comments are closed
via Ad Packs
9292