Customizing the appearance of Google Translate widget for mobile sites

My website - www.forex-central.net - features the Google Translate drop-down widget positioned at the top right corner of every page.

The only issue is that it appears to be too wide for my website at 5 cm. I have seen a 4 cm version on other sites, so I know that it is possible to adjust the size. However, I lack the technical expertise to modify the code myself.

The current code provided by Google for the widget usage is as follows:

<script type="text/javascript">function googleTranslateElementInit() { new google.translate.TranslateElement({ pageLanguage: 'en', gaTrack: true, layout: google.translate.TranslateElement.InlineLayout.SIMPLE }, 'google_translate_element');}</script><script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script> 

I would greatly appreciate any assistance with this matter! As a beginner, I have spent hours trying to resolve this issue with no success so far :-/

Answer №1

If you're looking to kickstart your project, consider starting with something along these lines:

.goog-te-menu-frame {
    max-width:100% !important; //adjust as needed
}

Additionally, you might want to implement the following:

.goog-te-menu2 { //the container for options table
    max-width: 100% !important;
    overflow: scroll !important;
    box-sizing:border-box !important; //addresses padding
    height:auto !important; //eliminates vertical scrolling
}

Unfortunately, modifying the second part is challenging due to the translate interface being embedded in an iframe on your webpage. Luckily, since it shares the same domain, we can manipulate it using Javascript like this:

$('.goog-te-menu-frame').contents().find('.goog-te-menu2').css(
    {
        'max-width':'100%',
        'overflow':'scroll',
        'box-sizing':'border-box',
        'height':'auto'
    }
)

However, this solution won't work until the element actually loads (asynchronously), which requires a workaround that can be found here. To tie it all together, here's what you should do:

function changeGoogleStyles() {
    if($('.goog-te-menu-frame').contents().find('.goog-te-menu2').length) {
        $('.goog-te-menu-frame').contents().find('.goog-te-menu2').css(
            {
                'max-width':'100%',
                'overflow':'scroll',
                'box-sizing':'border-box',
                'height':'auto'
            }
        )
    } else {
        setTimeout(changeGoogleStyles, 50);
    }
}
changeGoogleStyles();

Phew.

You can apply a similar approach to customize other aspects of the translate box or tweak the table styles to ensure it flows vertically instead of extending horizontally off-screen. For further guidance, refer to this answer.

EDIT:

Even this doesn't suffice, given Google re-applies the styles every time you interact with the dropdown. While attempting to modify height and box-sizing, Google consistently overrides those changes, yet overflow and max-width persist. To safeguard our styles from being overridden, we must employ inline styles and include !important declarations [sigh]. Here's how you can achieve this (I've replaced the selector with a variable for brevity and potentially minimal performance enhancement):

function changeGoogleStyles() {
    if(($goog = $('.goog-te-menu-frame').contents().find('body')).length) {
        var stylesHtml = '<style>'+
            '.goog-te-menu2 {'+
                'max-width:100% !important;'+
                'overflow:scroll !important;'+
                'box-sizing:border-box !important;'+
                'height:auto !important;'+
            '}'+
        '</style>';
        $goog.prepend(stylesHtml);
    } else {
        setTimeout(changeGoogleStyles, 50);
    }
}
changeGoogleStyles();

Answer №2

Utilizing the Google Translate widget involves embedding an iframe with content from a different domain, specifically files hosted on Google servers. Initially, attempting cross-site scripting to manipulate the iframe content proved unsuccessful for me. However, I devised an alternative approach by downloading and modifying two essential files utilized by the widget.

It is important to note that Google may make changes to its API in the future, requiring adjustments to any implemented hacks.

Requirements:
Assuming that the Google Translate widget functions correctly on your website but requires optimization for smaller screens, below is a sample of the initial code structure:

<div id="google_translate_element"></div>
<script type="text/javascript">
    function googleTranslateElementInit()
    {
        new google.translate.TranslateElement({pageLanguage:'de', layout: google.translate.TranslateElement.InlineLayout.SIMPLE}, 'google_translate_element');
    }
</script>
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>

If your original code differs from this example, adjustments will be necessary as per your specific setup.

Tools Utilized:
Primarily, Chrome DevTools were employed (can be adapted for other browsers).

Procedure:

  1. Right-click on the page containing the Google Translate widget using Google Chrome.
  2. Select Inspect. This action will reveal a window or side pane showcasing various HTML information.
  3. In the top menu, navigate to the Sources tab.
  4. Locate the following path within the sources tree:

    /top/translate.google.com/translate_a/element.js?cb=googleTranslateElementInit
    
  5. Click on the file displayed within the tree structure to view its contents.

  6. Below the code snippet of element.js, there is a button with curly brackets { }. Clicking this button helps organize the code for better clarity, aiding in subsequent steps.
  7. Right-click within the code section of element.js and choose Save as… to save the file within your website's file hierarchy. For instance:

    /framework/google-translate-widget/element.js
    
  8. Adjust your <script> tag to reference the local element.js file.

    <!--<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>-->
        <script type="text/javascript" src="../framework/google-translate-widget/element.js?cb=googleTranslateElementInit"></script>
    
  9. Confirm that your website now fetches element.js locally. Verify this change using Chrome DevTools to ensure the sourcing location under:

    /top/[your domain or IP]/framework/google-translate-widget/element.js?cb=googleTranslateElementInit
    
  10. The next step involves acquiring another necessary file from Google servers. Navigate through the sources tree to find:

    /top/translate.googleapis.com/translate_static/css/translateelement.css
    

    Upon locating the file, download it and click the curly brackets { }. Save the file within your website's directory structure like so:

    /framework/google-translate-widget/translateelement.css
    
  11. Edit line 66 in your website files' element.js:

    //c._ps = b + '/translate_static/css/translateelement.css';
    c._ps = '/framework/google-translate-widget/translateelement.css';
    

    This modification ensures that your website loads translateelement.css locally. Verify this change accordingly.

  12. Open your local translateeleent.css and append the provided styles at the end of the file. These styles aim to enhance visibility on small screens and are sourced from:

    /* Make all languages visible on small screens. */
    .goog-te-menu2 {
        width: 300px!important;
        height: 300px!important;
        overflow: auto!important;
    }
    .goog-te-menu2 table,
    .goog-te-menu2 table tbody,
    .goog-te-menu2 table tbody tr {
        width: 100%!important;
        height: 100%!important;
    }
    .goog-te-menu2 table tbody tr td {
        width: 100%!important;
        display: block!important;
    }
    .goog-te-menu2 table tbody tr td .goog-te-menu2-colpad {
        visibility: none!important;
    }
    

    Credit goes to the source from where these styles were borrowed: Google translate widget mobile overflow

  13. While the styling modifications may yield positive results regarding geometry, a critical component - the text displayed by the widget (“Select Language”, etc.) - becomes fixed to one language post-hack. To address this issue and cater to non-English speaking users, amendments must be made to ensure multilingual support. Check element.js for language settings around lines 51 and 69:

    c._cl = 'fr';
    
    _loadJs(b + '/translate_static/js/element/main_fr.js');
    

    Incorporate the following correction on line 51:

    c._cl = 'auto'; //'fr';
    
  14. Line 61 necessitates a more intricate adjustment due to the absence of an 'auto' value. Referencing the main.js file available on Google servers provides English as a fallback option, albeit we prefer the user's language. Examine the following location for clues:

    /top/translate.googleapis.com/translate_a/l?client=…
    

    This file contains information about supported source and target languages for translation. Validate if the browser's language setting corresponds to any target languages using the JavaScript constant navigator.language.

  15. Modify line 69 in element.js with the added logic to determine and render the Google Translate widget in the appropriate language based on the user's browser preferences:

    // determine browser language to display Google Translate widget in that language
    var nl = navigator.language;
    var tl = ["af","sq","am","ar","hy","az","eu","bn","my","bs","bg","ceb","ny",
              "zh-TW","zh-CN","da","de","en","eo","et","tl","fi","fr","fy","gl",
              "ka","el","gu","ht","ha","haw","iw","hi","hmn","ig","id","ga","is",
              "it","ja","jw","yi","kn","kk","ca","km","rw","ky","ko","co","hr",
              "ku","lo","la","lv","lt","lb","mg","ml","ms","mt","mi","mr","mk",
              "mn","ne","nl","no","or","ps","fa","pl","pt","pa","ro","ru","sm",
              "gd","sv","sr","st","sn","sd","si","sk","sl","so","es","sw","su",
              "tg","ta","tt","te","th","cs","tr","tk","ug","uk","hu","ur","uz",
              "vi","cy","be","xh","yo","zu"];
    var gl = "";
    if( tl.includes( nl )) gl = '_'+nl;
    else
    {
        nl = nl.substring(0, 3);
        if( tl.includes( nl)) gl = '_'+nl;
        else
        {
            nl = nl.substring(0, 2);
            if( tl.includes( nl)) gl = '_'+nl;
            else gl = '';
        }
    }
    _loadJs(b + '/translate_static/js/element/main'+gl+'.js');
    //_loadJs(b + '/translate_static/js/element/main_fr.js');
    

This comprehensive process should provide the desired outcomes.

Answer №3

Consider utilizing the following CSS snippet:

.custom-container, .custom-item { width: 150px !important;}

You have the flexibility to adjust the dropdown width by modifying the value of '150px'.

This solution should be effective. Feel free to reach out if any issues persist and I will gladly reassess.

Answer №4

In an effort to enhance the usability of Google Translate's iframe content, I have made adjustments to allow for scrolling functionality after the initial data has loaded.

function customizeGoogleTranslate() {
    new google.translate.TranslateElement({
        pageLanguage: 'en',
        layout: google.translate.TranslateElement.InlineLayout.SIMPLE,
        autoDisplay: false
    }, 'google_translate_element');

    setTimeout(function() {
        var translateIframe = document.querySelector('iframe.skiptranslate');
        if (translateIframe) {
            translateIframe.style.maxWidth = '100%';
            translateIframe.contentWindow.document.body.style.overflow = 'scroll';
        }
    }, 1000);
}

Answer №5

We encountered an issue where the content within the 'skiptranslate' iframe of Google Translate was not scrollable.

Below is a simpler solution compared to others provided:

If you already have jQuery installed on your page, you can enhance the googleTranslateElementInit function that initializes the iframe with these additional steps:

<script type="text/javascript">
        function googleTranslateElementInit() {
             new google.translate.TranslateElement({
                  pageLanguage: 'en',
                  layout: google.translate.TranslateElement.InlineLayout.SIMPLE
             }, 'google_translate_element');
             
             // Set the maximum width of the iframe using jQuery
             jQuery('iframe.skiptranslate').css('max-width', '300px');
                    
             // Add an aria element for accessibility
             jQuery('.skiptranslate').attr('aria-label', 'Google Translate');
    
             // Modify the 'scroll' attribute of jQuery('iframe.skiptranslate') > #document.body
             jQuery('iframe.skiptranslate').on('load', function () {
                   jQuery(this).contents().find('body').attr('scroll', 'yes');
                   jQuery(this).contents().find('body').attr('style', 'margin:0px;overflow:auto');
             });
        }
</script>

No jQuery? No problem! Check out this alternative using plain JavaScript:

<script type="text/javascript">
    function googleTranslateElementInit() {
        new google.translate.TranslateElement({
        pageLanguage: 'en',
        layout: google.translate.TranslateElement.InlineLayout.SIMPLE
        }, 'google_translate_element');


        // Add an aria-label for accessibility using plain JavaScript
        document.querySelectorAll('.skiptranslate').forEach(function (element) {
        element.setAttribute('aria-label', 'Google Translate');
        });

        // Adjust the 'scroll' attribute of iframes with class 'skiptranslate'
        document.querySelectorAll('iframe.skiptranslate').forEach(function (iframe) {
        iframe.addEventListener('load', function () {
        var body = this.contentWindow.document.body;
        body.setAttribute('scroll', 'yes');
        body.style.margin = '0px';
        body.style.overflow = 'auto';
        });
        // Set the maximum width of the iframe
        iframe.style.maxWidth = '300px';
    });
  
  }
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I create a table that is 100% width, with one column that has a flexible size and truncates text

I am currently facing an issue with a table nested within a div that is absolutely positioned on my webpage. I want to set specific widths for the second, third, etc columns while allowing the first column to automatically resize, even if it results in tru ...

Are my Angular CLI animations not working due to a version compatibility issue?

I've been working on a project that had Angular set up when I started. However, the animations are not functioning correctly. The mat input placeholder doesn't disappear when typing, and the mat-select drop-down is not working. Here is my packag ...

One method to add a hashtag before a variable in the HTML attribute value data-bs-target

Basically, I have set up a vue web application with a container containing multiple bootstrap cards. Each card has a button that is supposed to collapse a form for guests to apply. However, the issue arises when I click on the button of one card, as it col ...

The content div in CSS is causing the menu div to be displaced

I have encountered a difficulty in describing the issue at hand as I am still in the learning phase and consider myself a beginner. Within my container div, there are two other divs - one for the menu and another for the content. Both of these divs float ...

Chrome is the only browser displaying background images

My current issue is that the background image only appears on Chrome and not on Firefox or Edge. I am trying to have a different background image each time the page loads. $(document).ready(function() { var totalBGs = 5; var rnd = Math.floor(Math.ran ...

Varied spacing between horizontal and vertical items in a list

The issue with the spacing between horizontal and vertical list items is perplexing. Despite having identical margin, padding, height, and width, they seem to display differently. While manual adjustment of margins or paddings can resolve this, I am curiou ...

How can I customize button colors in react-bootstrap components?

Changing colors in react-bootstrap may be a challenge, but I'm looking to customize the color of my button beyond the primary options. Any suggestions on how I can achieve this using JS and SCSS? ...

Switch to light mode upon clicking the toggle?

On the top left corner of this page, there's a toggle for "Light/Dark mode". Clicking on 'Light mode' smoothly transitions to dark mode without any issues. However, once it's in Dark mode and you try to switch back to 'light mode&a ...

Navigating to the appropriate section by clicking on a navbar item with Bootstrap 5: A step-by-step guide

Hi everyone! I am just starting out in front-end development and I was hoping to get some clarification on a topic. I need to create a one-page website where the navigation bar links scroll down to the correct sections when clicked. It's all on one pa ...

Using the "position: absolute" property will not contribute to the

I am facing an issue with aligning two div elements inside a parent div. Currently, they are rendering side by side: <image><info> However, on smaller screens, I want them to render one under the other and swap positions, like this: <inf ...

Can you provide guidance on centering a "frame" and aligning elements within it using CSS?

In creating my webpage, I am looking to design a virtual frame that is centered on the page. Within this frame, I want to be able to align various elements like images, text, and more using CSS properties. Let me explain with an example: I envision being ...

Left-aligned arrow for Material UI select dropdown

Just starting out with material ui and I'm trying to grasp a few concepts. I have a basic select component but encountering two issues. Firstly, I'd like to move the arrow icon of the select to the left side instead of the right. Additionally, ...

Placing a Label Next to an Input Field using Bootstrap 4

Is there a way to position the label right next to the input form? I've attempted different methods without success. Could you please review my code below? <div class="modal-body"> <form class="form-horizontal"> <div cl ...

Changing the color of a div element dynamically with JavaScript

Is there a way to improve the code below so that the background color of this div box changes instantly when clicked, without needing to click twice? function updateBackgroundColor(platz_id) { if(document.getElementById(platz_id).style.backgroundCol ...

Alter the appearance of a webpage by pressing a key. (Using Vue.js)

Is there a way to change the CSS style value of an element when a specific keybind is pressed by the user? <textarea id="check" v-model="text" v-on:keydown.ctrl.up="decreaseFont" > I am able to confirm that the ...

Designing a nested box layout with bootstrap HTML/CSS styling

Can anyone provide guidance on how to create a HTML/CSS layout similar to the image below? I am specifically struggling with designing the silver "Add corkscrew" box, a white box beneath it, and then another silver box nested within. Any suggestions on ho ...

How to create fading directional navigation arrows using the Orbit jQuery plugin?

I want the navigation arrows to only appear when the user hovers over the "#featured" div or its display. My current code achieves this, but the transition is quite abrupt: $("#featured, div.slider-nav").hover(function(){ $("div.slider-nav").animate({ ...

Expanding the width of a list-group with Bootstrap to fill the entire div

I am working with a div that has a height of 200px. How can I make sure the ul items are divided into equal rows within the div, instead of always aligning to the top? To illustrate this, I have colored the div green. As I will be using ngFor in my ul, the ...

Three divs are positioned within the parent element and collectively fill the entire height. The first and last div have varying

I attempted to replicate the design shown in the image below: https://i.sstatic.net/Q7sTI.png Initially, I was successful in achieving this using JavaScript. However, when attempting to recreate the same effect using only CSS without any JavaScript, I en ...

Foundation Unveil Modal hidden from view

I'm currently integrating modals using Foundation 5 in a Rails application. The issue I'm facing is that the modal only works when the page is not scrolled down. If you scroll to the bottom of the page and try to activate the modal by clicking ...