Skip to content

Integrating Mercury with CSS Frameworks

nreckart edited this page Mar 27, 2012 · 2 revisions

Mercury comes with its own set of CSS styles for its various elements, such as toolbars, modals, panels, and forms. These are great to get up and running with Mercury quickly, but if you're integrating Mercury into an application that is already using a CSS framework, such as Twitter's Bootstrap, you'll probably want to use your existing framework along with Mercury. This can be tricky, especially if your framework uses global styles, which is often the case with forms.

Mercury tries to avoid using global styles as much as possible. Its form styles in particular are namespaced under the 'mercury-form' CSS class and all of the built-in forms, such as those in the Media and Link modals, are assigned this class. If you create custom Mercury modals or panels, you will need to assign the 'mercury-form' class to your forms to ensure that they are styled the same as the built-in forms.

It is a Mercury design decision to not force the use of any one particular CSS framework, such as Bootstrap. Not everyone uses the same frameworks and by keeping Mercury as self contained as possible, the ability to use any framework you choose is possible with a little extra work on your part. Since CSS frameworks are often closely tied to a specific HTML structure, you typcially cannot just plug an external CSS framework into Mercury and have everything working out of the box. Some extra work will need to be done.

Twitter Bootstrap Integration

Twitter has been kind enough to open source a great CSS framework called Bootstrap. Bootstrap is more than just CSS and includes a host of JavaScript plugins that allow you to quickly build UI components. Within the context of Mercury, Bootstrap really shines when creating forms that are displayed within Mercury modals, such as those for snippet options.

To integrate Bootstrap into Mercury, you must first ensure that the necessary Bootstrap CSS and JavaScript files are included within the same view as the Mercury editor.

(TODO: Elaborate on how to install Bootstrap alongside Mercury)

Once Bootstrap is installed, you'll notice that the display of the built-in modals included with Mercury, including the Media, Link, and Table modals, are broken. This is because Bootstrap defines global form styles, which collide with Mercury's form styles. Mercury and Bootstrap both require a specific HTML structure in order to utilize their CSS styles and, unfortunately, the two structures are drastically different. This means you will have to rewrite the built-in Mercury modals to conform to the Bootstrap HTML structure. Fortunately, this is fairly straight forward, especially if you're using Rails.

If you're using Rails, you can easily override the views for the built-in Mercury modals by creating files of the same name within app/views/mercury/modals/. For example, to override the built-in Link modal, create app/views/mercury/modals/link.html within your application. This file will now be rendered instead of the built-in Mercury view.

Below is what link.html would look like rewritten for Bootstrap.

<form id="mercury_link" class="form-horizontal custom-mercury-form" style="width: 600px;">
  <div class="mercury-display-pane-container">
    <div class="mercury-display-pane">

      <fieldset id="link_text_container">
        <div class="control-group">
          <label class="control-label" for="link_text">Link Content</label>
          <div class="controls">
            <input type="text" id="link_text" name="link[text]" class="span5">
            <p class="help-block">The text that appears inside the link.</p>
          </div>
        </div>
      </fieldset>

      <fieldset>
        <legend>Standard Links</legend>
        <div class="control-group" id="link_external_url_input">
          <label class="control-label" for="link_external_url">
            <input name="link_type" type="radio" value="external_url" checked="checked">
            URL
          </label>
          <div class="controls">  
            <input class="selectable span5" id="link_external_url" name="link[external_url]" type="text">
          </div>
        </div>
      </fieldset>

      <fieldset>
        <legend>Index / Bookmark Links</legend>
        <div class="control-group" id="link_existing_bookmark_input">
          <label class="control-label" for="link_existing_bookmark">
            <input name="link_type" type="radio" value="existing_bookmark"/>
            Existing Links
          </label>
          <div class="controls">
            <select class="selectable span5" id="link_existing_bookmark" name="link[existing_bookmark]"></select>
          </div>
        </div>
        <div class="control-group" id="link_new_bookmark_input">
          <label class="control-label" for="link_new_bookmark">
            <input name="link_type" type="radio" value="new_bookmark">
            Bookmark
          </label>
          <div class="controls">
            <input class="selectable span5" id="link_new_bookmark" name="link[new_bookmark]" type="text">
          </div>
        </div>
      </fieldset>

      <fieldset>
        <legend>Options</legend>
        <div class="control-group" id="link_target_input">
            <label class="control-label" for="link_target">Link Target</label>
            <div class="controls">
              <select class="span5" id="link_target" name="link[target]">
                <option value="">Self (the same window or tab)</option>
                <option value="_blank">Blank (a new window or tab)</option>
                <option value="_top">Top (removes any frames)</option>
                <option value="popup">Popup Window (javascript new window popup)</option>
              </select>
            </div>
        </div>
        <div id="popup_options" class="link-target-options" style="display:none">
          <div class="control-group" id="link_popup_width_input">
            <label class="control-label" for="link_popup_width">Popup Width</label>
            <div class="controls">
              <input class="span2" id="link_popup_width" name="link[popup_width]" type="text">
            </div>
          </div>
          <div class="control-group" id="link_popup_height_input">
            <label class="control-label" for="link_popup_height">Popup Height</label>
            <div class="controls">
              <input class="span2" id="link_popup_height" name="link[popup_height]" type="text">
            </div>
          </div>
        </div>
      </fieldset>

    </div>
  </div>

  <div class="mercury-display-controls">
    <input class="btn btn-primary" name="commit" type="submit" value="Insert Link">
  </div>

</form>

Notice that the 'mercury-form' class is not assigned to the form above. Instead, it has been assigned a 'custom-mercury-form' class. We don't want to include Mercury's built-in form styles because they will collide with Bootstrap. The custom-mercury-form styles are up to you and should be included in mercury_override.css, or another CSS file that gets included within the editor view. You do not have to name your custom styles class 'custom-mercury-form'. You can call it whatever you want.

Since the JavaScript associated with the Link modal is tied to the HTML structure of the page, you will also need to override the built-in JavaScript logic. Take a look at the Extending Mercury page for more on extending/overriding Mercury features. For the Link modal, the file you'll want to override is vendor/assets/javascripts/mercury/modals/insertlink.js.coffee.

You will need to rewrite the view and possibly the JavaScript for the other built-in Mercury modals as well, including the options view modal for any Snippets that you may have. Once this is complete, you should be in Bootstrap heaven and you are now free to use all the goodness of Bootstrap when designing your modals.