Advertisement
  1. Web Design
  2. UX/UI
  3. Navigation

How to Code an Inline Sharing Menu

Scroll to top
Read Time: 8 min

In this tutorial, we will learn how to build a so-called “inline sharing menu”. This interface works by popping-up a menu which allows readers to share the page, quoting the highlighted text. You’ll find a similar interface on a few popular sites like Medium.

Before we begin building our sharing menu, we’ll examine how this similar interface in Medium works more closely, such as when it is shown and how it is positioned against the highlighted area. This is a helpful step that will provide us proper technical insight, eventually also determining how we will write our codes our own code.

Let’s go!

Examining the Medium Interface

In the following image, we can see that the sharing menu in Medium appears at the centre of the highlighted text, regardless of the length; whether we select only a single word, a sentence, or the whole paragraph.

Highlighted word with the sharing button in MediumcomHighlighted word with the sharing button in MediumcomHighlighted word with the sharing button in Mediumcom
Inline Sharing UI in Medium 

If we look under the hood via Chrome DevTools, we can find the sharing menu position is given through top and left property in the the inline style. We can see the sharing button is also given with an additional modifier class, highlightMenu--active, which makes it visible.

Note: If you are not yet familiar with terms like Modifier, Block, and Element, you should have a look at this earlier tutorial: An Introduction to the BEM Methodology.

Styles that position the inline sharing menu in Medium

In the Styles tab, we can see its initial position is set through CSS with the absolute position, the z-index property to raise above the other elements on the page, the top, and with the visibility property to put the sharing buttons out of sight.

To summarise, we will need to:

  1. Retrieve the length of the selected area so that we can determine the centre point of the selection.
  2. Create a modifier to show the element.
  3. Set the sharing menu postion with the top and left property added through inline styles.

Build the Sharing Menu 

In this example we’ll include Facebook and Twitter buttons within the sharing menu. We deliver the Facebook and Twitter icon with SVG, wrapped within a button and a couple of div elements. Additionally, as you can see from the following snippet, we also add a span element to form the triangle at the bottom of the menus.

1
<div class="sharing">
2
    <div class="sharing__buttons">
3
        <button id="share" title="Share">
4
            <svg class="icon icon--facebook" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512; width: 24px; height: 24px" xml:space="preserve"><g></g><g><g><path d="M426.8,64H85.2C73.5,64,64,73.5,64,85.2l0,341.6c0,11.7,9.5,21.2,21.2,21.2H256V296h-45.9v-56H256v-41.4 c0-49.6,34.4-76.6,78.7-76.6c21.2,0,44,1.6,49.3,2.3v51.8l-35.3,0c-24.1,0-28.7,11.4-28.7,28.2V240h57.4l-7.5,56H320v152h106.8 c11.7,0,21.2-9.5,21.2-21.2V85.2C448,73.5,438.5,64,426.8,64z"/></g></g></svg>
5
        </button>
6
        <button id="tweet" title="Tweet">
7
            <svg class='icon icon--twitter' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 512 512' style='enable-background:new 0 0 512 512; width: 24px; height: 24px' xml:space='preserve'><path d='M492,109.5c-17.4,7.7-36,12.9-55.6,15.3c20-12,35.4-31,42.6-53.6c-18.7,11.1-39.4,19.2-61.5,23.5

8
                C399.8,75.8,374.6,64,346.8,64c-53.5,0-96.8,43.4-96.8,96.9c0,7.6,0.8,15,2.5,22.1c-80.5-4-151.9-42.6-199.6-101.3

9
                c-8.3,14.3-13.1,31-13.1,48.7c0,33.6,17.2,63.3,43.2,80.7C67,210.7,52,206.3,39,199c0,0.4,0,0.8,0,1.2c0,47,33.4,86.1,77.7,95c-8.1,2.2-16.7,3.4-25.5,3.4c-6.2,0-12.3-0.6-18.2-1.8c12.3,38.5,48.1,66.5,90.5,67.3c-33.1,26-74.9,41.5-120.3,41.5

10
                c-7.8,0-15.5-0.5-23.1-1.4C62.8,432,113.7,448,168.3,448C346.6,448,444,300.3,444,172.2c0-4.2-0.1-8.4-0.3-12.5

11
                C462.6,146,479,129,492,109.5z'/>
12
            </svg>
13
        </button>
14
    </div>
15
    <span class="sharing__triangle"></span>
16
</div>

There’s no definitive rule in term of the colours and the shape of the menu; feel free to style the menu to match your site design. Worth paying attention to are the button size; the height and the width. Our sharing menu is, as you can see below, 84px wide and 40px tall. We will use these two values to position the sharing menu at the centre of the highlighted area later on.

Inline sharing menu size inspected through Chrome DevToolsInline sharing menu size inspected through Chrome DevToolsInline sharing menu size inspected through Chrome DevTools

The styles thats set the initial position and visibility.

1
.sharing {
2
	position: absolute;
3
	visibility: hidden;
4
	top: 0;
5
	left: 0;
6
	z-index: 500;
7
}

And lastly, the class that we will append to make the sharing button visible.

1
.sharing--shown {
2
	visibility: visible;
3
}

Make the Sharing Menu Functional

At this point, our inline sharing menu should not be visible on the page. Also, when we click the Facebook and the Twitter button, the sharing window is nowhere to be seen. So, in this section, we’ll write the JavaScript to make our buttons functional. And we begin with the following, getHighlight() function.

1
function getHighlight() {
2
3
    var selection = window.getSelection(); // 1.

4
5
    var object = {
6
		parent : null,
7
		text   : '',
8
		rect   : null
9
    };
10
11
	// If selection is not empty.

12
    if ( selection.rangeCount > 0 ) {
13
        object = {
14
            text   : selection.toString().trim(), // get the text.

15
            parent : selection.anchorNode.parentNode, // get the element wrapping the text.

16
            rect   : selection.getRangeAt(0).getBoundingClientRect() // get the bounding box.

17
        };
18
    }
19
20
    return object; // 2.

21
}

This function will:

  • Retrieve the the highlighted area using the native JavaScript function, getSelection().
  • Return an Object containing the selected text, the element wrapping the text, and the Rectangle Object of the selected area which gives us the size as well as its position —topbottomleft, and right — within the page.

Our next function is called showMenu(). As the name implies, this function will reveal the sharing menu.

1
var sharing = document.querySelector( '.sharing' );
2
3
function showMenu() {
4
5
	// 1.

6
    var highlight = getHighlight();
7
8
	// 2.

9
    if ( highlight.text === '' ) {
10
11
        sharing.setAttribute( 'class', 'sharing' );
12
        sharing.style.left = 0;
13
        sharing.style.top  = 0;
14
15
        return;
16
    }
17
18
	// 3.

19
	/**

20
	 * Only show the sharing button if the selected is a paragraph.

21
	 */
22
    if ( highlight.parent.nodeName !== 'P' ) {
23
        return;
24
    }
25
26
	// 4.

27
    var width = ( highlight.rect.width / 2 ) - 42;
28
    /**

29
     * The "42" is acquired from our sharing buttons width devided by 2.

30
     */
31
32
    sharing.setAttribute( 'class', 'sharing sharing--shown' );
33
	sharing.style.left = ( highlight.rect.left + width ) + 'px';
34
	sharing.style.top  = ( highlight.rect.top - 40 ) + 'px';
35
	/**

36
	 * "40" is the height of our sharing buttons.

37
	 * Herein, we lift it up above the higlighted area top position.

38
	 */
39
}

Specifically, the code in this function do the following:

  1. Get the Object from getHighlighted() function.
  2. Hide and set the sharing menu to its initial position when the highlighted area is empty; it does not contains text.
  3. Prevent the buttons from appearing if the highlighted text is not wrapped within a paragraph.
  4. Lastly, set the top and the left position, and append the sharing--shown class to make the sharing buttons visible. I’ve also added a few lines of inline comments describing where some of the defined numbers are derived from.

We’re going to assume that most users use mouse to highlight the content on the web, thus we bind this function on the mouseup event. Mobile devices will usually have their own contextual menus on text selection, so we’re focusing on the web for this tutorial.

safari iossafari iossafari ios
Text selection in Safari iOS

We delay the execution though by 100ms using the setTimeout() function, to ensure the content is properly selected.

1
document.body.addEventListener( 'mouseup', function() {
2
     setTimeout( showMenu, 100 );
3
} );

Our last function, openShareWindow(), is to launch the sharing window when the buttons in the menu are clicked. In this tutorial, we will primarily use it to deliver the Twitter sharing window since Facebook has its own JavaScript SDK.

1
function openShareWindow( url, w, h ) {
2
3
	var screenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
4
	var screenTop = window.screenTop !== undefined ? window.screenTop : screen.top;
5
	var width = window.innerWidth ? window.innerWidth : doc.documentElement.clientWidth ? doc.documentElement.clientWidth : screen.width;
6
	var height = window.innerHeight ? window.innerHeight : doc.documentElement.clientHeight ? doc.documentElement.clientHeight : screen.height;
7
8
	var left = ( ( width / 2 ) - ( w / 2 ) ) + screenLeft;
9
	var top = ( ( height / 2 ) - ( h / 2 ) ) + screenTop;
10
11
	var newWin = window.open( url, "", "scrollbars=no,width=" + w + ",height=" + h + ",top=" + top + ",left=" + left );
12
13
	if ( newWin ) {
14
		newWin.focus();
15
	}
16
}

Click...Click...

Next, we bind the sharing buttons with the click event and attach a function that will launch the sharing window.

1
// Facebook.

2
document.getElementById( 'share' ).addEventListener( 'click', function() {
3
4
    var highlight = getHighlight();
5
6
    if ( highlight.text !== '' && highlight.parent.nodeName === 'P' ) {
7
        FB.ui({
8
            method : 'share',
9
            mobile_iframe: true,
10
            href   : 'http://bitly.com/2aiHmCs',
11
            quote  : highlight.text // pass the text as Quote

12
        });
13
    }
14
15
    event.preventDefault();
16
} );

For the Facebook sharing button, we use the Facebook JavaScript SDK. The SDK allows us to pass text to appear in the sharing window through the quote parameter.

Twitter does not provide a JavaScript SDK in this way. So here we use our function, openShareWindow(), and pass a formatted URL that complies with their guidelines along with the size of the window.

1
document.getElementById( 'tweet' ).addEventListener( 'click', function() {
2
3
    var highlight = getHighlight();
4
5
    if ( highlight.text !== '' && highlight.parent.nodeName === 'P' ) {
6
7
        var docURL = encodeURIComponent( 'http://bitly.com/2aiHmCs' );
8
        var tweetText = encodeURIComponent( highlight.text );
9
        var tweetURL = 'https://twitter.com/intent/tweet?via=wdtuts&url=' + docURL + '&text=' + tweetText;
10
11
        openShareWindow( tweetURL, 600, 420 );
12
    }
13
14
    event.preventDefault();
15
} );

When we click the Twitter sharing button, it should launch a window that appears, as follows.

Wrapping Up

We are all set with our inline sharing menu! Head over to the demo to see it in action, or the source code to look the functions in full. Next, you can improve the inline sharing menu with transitions or animation to deliver a more engaging experience.

Further Resources

There are several JavaScripts APIs that we used to get the sharing menu up and running. Some of them have been mentioned in previous Envato Tuts+ tutorials, while others might be completely new to you. So, here I’ve included references to complement this tutorial.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.