Swap placeholder text based on resolution (media query)
Asked Answered
P

7

33

I'm working on a responsive design. I've hit a bit of a wall with there not being enough space for an input box and it's label. So I have decided to hide the label on smaller screen sizes.

At present it has the placeholder text your email inside it, but I want only on screens less than 400 (so up to 399px wide) a different place holder of Join our newsletter.

I reckon there will need to be some JS to perform this, rather than anything with CSS.

Essentially: if screen size less than 400: placeholder text = Join our newsletter

else: placeholder text = Your email.

Here is the HTML I have:

<div id="mc_embed_signup">
<input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL" placeholder="Your Email">
</div>
Pierrepierrepont answered 11/8, 2013 at 20:0 Comment(1)
If you're looking for Pure CSS solution, you can create 2 input with different placeholders, and manage their display property by CSS3 @media.Arabele
A
31

As a pure CSS solution, we could have two <input>s - having different placeholders - which are shown in different screen sizes - Example here:

input.large { display: inline-block; }
input.small { display: none; }

@media (max-width: 399px) { 
  input.large { display: none; }
  input.small { display: inline-block; }
}
<input type="email" name="email[]" class="required email large" id="mce-EMAIL" placeholder="Your Email">
<input type="email" name="email[]" class="required email small" placeholder="Join our newsletter">

Important notes:

  1. In this case we should make sure that the id of our two inputs are different. Besides, If id is added to <input> just because of its usage for label elements, we could just wrap the input by label instead.

  2. Using more than one input which have the same name, will override the name/value pair in HTTP request method.

One possible solution is to use an array name value for name attribute, (as example above) and handle it at server-side (It's better to keep name values in lowercase).

Alternatively, we could disable the hidden input in order to prevent its value from being sent to server:

$('input:hidden').prop("disabled", true);

Using JavaScript in a Pure CSS Solution? Maybe... maybe not... but nowadays no websites in the modern world are empty of JavaScript. If it helps to get rid of the problem, it's alright to get hands a little dirty!.

Arabele answered 11/8, 2013 at 20:23 Comment(3)
Excellent idea! Hadn't thought about it this way. Thanks!Pierrepierrepont
this is a clever solution, and works nicely in Angular applications if you bind both fields to the same data modelGeocentric
Simple but elegant solution. Thanks.Croix
D
18
if ($(window).width() < 400 ) {
    $("input[type='email']").attr("placeholder","join our newsletter");
}
else { $("input[type='email']").attr("placeholder","your email");}

demo: http://jsfiddle.net/fcrX5/

Dalrymple answered 11/8, 2013 at 20:12 Comment(0)
M
9

While a bit hacky, this is possible to do in pure HTML/CSS (no javascript required) without duplicating elements in the DOM if you only need to show/hide the text, not change it.

The hack is to simply style of the placeholder text differently depending on width (or whatever your media query is) and change the opacity to make it appear or disappear, like so:

input.responsive::-webkit-input-placeholder,
input.responsive::-moz-placeholder,
input.responsive:-moz-placeholder,
input.responsive:-ms-input-placeholder { 
    color: rgba(25, 25, 25, 1.0);
}

@media (max-width: 399px) { 
    input.responsive::-webkit-input-placeholder,
    input.responsive::-moz-placeholder,
    input.responsive:-moz-placeholder,
    input.responsive:-ms-input-placeholder { 
        color: rgba(0, 0, 0, 0);
    }
}
Magree answered 7/4, 2014 at 6:12 Comment(1)
As far as I can tell, that syntax does not work. In order to make it work I had to create individual entries, such asFraya
F
1

This script includes initial setting of the placeholder and changing text on window resize:

    //set responsive mobile input field placeholder text
    if ($(window).width() < 769) {
        $("input").attr("placeholder", "Short text");
    }
    else {
        $("input").attr("placeholder", "Long text for wide input filed");
    }
    $(window).resize(function () {
        if ($(window).width() < 769) {
            $("input").attr("placeholder", "Short text");
        }
        else {
            $("input").attr("placeholder", "Long text for wide input field");
        }
    });
Funereal answered 14/2, 2017 at 16:22 Comment(0)
N
0

Just check for the screen size, and act accordingly :

$(function() {
    var txt = screen.width < 400 ? 'Join our newsletter' : 'Your email';
    $('#mce-EMAIL').attr('placeholder', txt);
});

Note that you explicitly asked for "screen size", window size and resize events are something else entirely.

Nascent answered 11/8, 2013 at 20:7 Comment(0)
W
0

if you use angular and lodash you can use this directive I've written for my use in one projects where the designer insisted...

lodash is used only to save us writing the debouncer function for window.resize events, can be replaced in 5 minutes of boilerplate setTimeout thingy...

angular.module('yourModuleNameHere').directive('mediaPlaceholder', function    ($window, $parse) {
    return {
        restrict: 'A',
        link: function ($scope, $elem, $attrs) {
            var defObj = $parse($attrs.mediaPlaceholder)($scope);

            function setPlaceholder() {
                var lastFitting, windowWidth = $($window).width();
                angular.forEach(defObj, function (placeholderValue,widthSetting) {
                    if (parseInt(widthSetting) <= windowWidth) {
                        lastFitting = placeholderValue;
                    }
                });
                $elem.attr('placeholder', lastFitting);
            }

            setPlaceholder();
            $($window).resize(_.debounce(setPlaceholder, 40));
        }
    };
})

use like this:

<input type="search" media-placeholder="{0:'search',989:'long search placeholder'}">
Whither answered 30/12, 2014 at 14:23 Comment(0)
J
0

Based on @hashem's excellent answer above, here is a Bootstrap approach.

Using Bootstrap 4.5, the standard @media query breakpoints are at:

  • xs - < 576px
  • sm - 576px and up
  • md - 768px and up
  • lg - 992px and up
  • xl - 1200px and up

See: https://getbootstrap.com/docs/4.5/layout/overview/#responsive-breakpoints

Assuming you want to use text above the input control for the xs screen size, and a placeholder for sm screen size and up, here is how one can do this using Bootstrap:

<div class="d-flex">
  ...
  <!-- size xs: use text above input. -->
  <div class="d-block d-sm-none mx-auto my-0 text-center">
    LABEL TEXT
    <div class="d-flex flex-row">
      <input id="input-narrow" class="mx-auto my-0 p-1 text-center">
    </div>
  </div>
  <!-- size sm and up: use placeholder -->
  <div class="d-none d-sm-flex flex-row flex-nowrap mx-auto my-0">
      <input id="input-wide" class="mx-auto my-0 p-1 text-center" placeholder="LABEL TEXT">
  </div>
  ...
</div>
Joshuajoshuah answered 19/1, 2021 at 1:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.