Hosting maps in the hidden container

Open in CodeSandbox

The map content fills the container it is in. At the time of initialization, the map must be able to detect the dimensions of the container.

If the container isn't ready at the time of map initialization, the map dimensions will be null (0x0), which means that the map won't be visible.

The map is invisible on the inactive jQuery.UI tab because the CSS 'display: none' property is used for hiding tabs. An element that has 'display: none' doesn't know its actual dimensions. The easiest solution is to initiate calculating map sizes when switching tabs, by calling the fitToViewport() command. Another workaround for the problem in the example (using jQuery.UI) is to use an alternative method for hiding tabs by redefining the standard jQuery.UI classes:

.ui-tabs .ui-tabs-hide { position: absolute !important; left: -10000px !important; display: block !important; }

<!DOCTYPE html>

<html>
    <head>
        <title>Examples. Hosting maps in the hidden container</title>
        <meta
            http-equiv="Content-Type"
            content="text/html; charset=UTF-8"
        />
        <!--
        Set your own API-key. Testing key is not valid for other web-sites and services.
        Get your API-key on the Developer Dashboard: https://developer.tech.yandex.ru/keys/
    -->
        <script
            src="https://api-maps.yandex.ru/2.1/?lang=en_RU&amp;apikey=<your API-key>"
            type="text/javascript"
        ></script>

        <!--
        Main JQuery library.
        Yandex provides hosting of JavaScript libraries
    -->
        <script
            src="https://yandex.st/jquery/2.2.3/jquery.min.js"
            type="text/javascript"
        ></script>

        <!-- JQuery.UI library. Use it to work with tabs -->
        <script
            src="https://yandex.st/jquery-ui/1.11.2/jquery-ui.min.js"
            type="text/javascript"
        ></script>

        <!-- CSS JQuery.UI tabs. Used for rendering tabs -->
        <link
            rel="stylesheet"
            href="https://yandex.st/jquery-ui/1.8.23/themes/humanity/jquery.ui.all.min.css"
            type="text/css"
        />

        <script src="hiddendiv.js" type="text/javascript"></script>
    </head>

    <body>
        <div id="tabs" style="width: 100%">
            <ul>
                <li><a href="#tab-1">Description</a></li>
                <li><a href="#tab-2">Map</a></li>
            </ul>
            <div id="tab-1">
                <p>The map of Moscow is shown on the Map tab</p>
            </div>
            <div
                id="tab-2"
                style="width: 100%; height: 300px; padding: 0;"
            ></div>
        </div>
    </body>
</html>
ymaps.ready(init);

var myMap;

function init() {
    /**
     * Initializing tabs.
     * After executing the tabs() command, tab-2 gets style='display:none'.
     * The map will be initialized, but the size will be null.
     * This is a good thing in this case, since the invisible map won't load invisible tiles.
     */
    $("#tabs").tabs();
    myMap = new ymaps.Map("tab-2", {
        center: [55.76, 37.64], // Moscow
        zoom: 10,
    });

    /**
     * We'll recalculate the map size when the new tab is displayed.
     * The map will get the maximum possible values when its tab is activated
     * and null values when the first tab is selected.
     * We'll subscribe to the 'tabsshow' event (not 'tabselect',
     * since it requires that the element with the map is already visible).
     */
    $("#tabs").bind("tabsshow", function (event, ui) {
        myMap.container.fitToViewport();
    });
}