1

We have an asp:Button control:

<asp:Button ID="btnLogin" AccessKey="l" runat="server" OnClick="btnLogin_Click" EnableViewState="false"></asp:Button>

that is rendered as html below:

<input type="submit" name="btnLogin" value="Login
[Enter]" id="btnLogin" accesskey="l" class="serverButton">

We set the text of the button as follows:

btnLogin.Text = "Login\n[Enter]";

Note the new line between Login and [Enter]

Up to Chrome version 47 this was rendering correctly. I.e. Login on one line and [Enter] directly beneath it. Since Chrome version 48 this now renders on a single line (E.g. Login[Enter]). We have attempted to implement Wrapping an HTML input button's text value over multiple lines and other options (e.g. changing the inputs to a button with a <br/> inside it).

Changing the hundreds of asp:Buttons with multiple lines to html <button> controls is not exactly feasible or desirable.

Currently this is working on all IE's up to and including 11, Edge, Firefox and Safari and previous versions of Chrome.

Any suggestions would be appreciated.

AJ.

Community
  • 1
  • 1
AnthonyJ
  • 405
  • 1
  • 6
  • 9

1 Answers1

1

As you elude to, and have probably already discovered, you can accomplish this in a fairly browser independent way by using <button>. However you also implied that you're not interested in that approach, but if you change your mind, perhaps the simplest way to do that would be to create a custom control that inherits from System.Web.UI.WebControls.Button but replace the Render to generate a <button> element. This will of course probably also effect other aspects of your code including both behavior and styling, but you might be able to account for those issues en mass through the custom/user control. This is the approach I would take and recommend.


CSS based approaches


1. Using :before

input elements' content cannot be manipulated by CSS (one could argue they don't have content at all, but that's not exactly what the spec says - here's a good analysis of that point), but if you wrap the input in a div, you can add :before to the div and then using content and some positioning, lay the text on top of the blank input. The primary advantage here is that you can control the line break explicitly, and then use text-align:center on the text itself, so you don't have to be quite as meticulous with spacing, font sizes etc. The disadvantage is that the positioning of the wrapper div and the input might be different for each instance of the button you want to replace. There is also the fact that you can't set the text via the button itself in the code behind, but I don't see this as a showstopper. You would either have to pass the text from server to client and set it on page load, or make the div runat='server' and do it in the code behind.

You may want to use something like jQuery's .wrap(), or similar, to actually wrap all your buttons.

Markup:

<div class="input-lb">
    <asp:Button ID="btnLogin" runat="server"/>
</div>

CSS:

.input-lb:before {
    content:"Login\a[Enter]"; /* \a to get line break with css content */
    white-space:pre-line; /* critical to collapse whitespace but not line breaks */
    text-align:center; /* the primary advantage over my previous approach */
    z-index: 100; /* must be higher than that of the input, so text is on top */
    pointer-events:none; /* so you can click the button underneath the text */
    position: relative; /* required */
    display:inline-block; /* you may not need/want this */
    width: 60px; /* You will have to play around with the position, including the input's styling below */
    left:35px;
    bottom:3px;
}

.input-lb input {
    width:70px;
    height:40px;
    position:relative;
    left:-35px;
 }

2. Retaining <input>

The idea is to limit the width of the button and force a line-wrap. I'm only leaving this approach here for reference. Using this is very ugly, even more so than the first approach, and it doesn't really allow you to center the words at all.

Markup stays the same as your original post.

CSS:

white-space: pre;
width: 60px;
word-wrap: break-word;

With the exact text for the button being:

string.Format("Login {0} [Enter]", Environment.NewLine);

NOTE: the spaces before and after the Environment.NewLine

You will have to play around with the width and spaces in the text to try to get the line break in the correct place and make the text look even remotely centered.

Community
  • 1
  • 1
Eric Lease
  • 3,894
  • 1
  • 24
  • 43
  • 1
    Thanks Eric. We are looking to possibly implement something like this http://forums.asp.net/t/1518381.aspx?Override+Button+Control if we have to. Would prefer not having to make any changes obviously but if it comes to it overriding the Render event might be a starting point – AnthonyJ Feb 01 '16 at 06:02
  • @AnthonyJ Ah, `ControlAdapter`, I hadn't even thought of that. Yes, that's a more direct way of creating the custom behavior that you would get from the custom or user control. I would say go with that actually if you can get it to work because then you don't have to worry about messing with positioning of text/button for each different text value. – Eric Lease Feb 01 '16 at 06:13
  • @AnthonyJ I see you marked this accepted. Thank you, but did you actually end up using one of those approaches I mentioned, or did you use a control adapter, or maybe something else? If you actually used your own solution it is ok to post the answer yourself and accept it - little late for the latter now though. Just curious what ended up working the best for you. – Eric Lease Feb 02 '16 at 02:45
  • We haven't implemented anything just yet but we will probably go for the ControlAdapter. I marked your item as the answer as you have also provided valid solutions and although we might not use them, someone in future might need to. :-) – AnthonyJ Feb 02 '16 at 03:20