9

I have a page which generates a phone number in HTML, like this:

<div class="phone">01987123456</div>

What I want is to simply put a space inside the number, like so:

01987 123456

The generated number and HTML will always be the same, but I only have access to client side code (HTML / CSS / Javascript / etc).

I want to find a way of achieving all of this without using Javascript if possible, so Ideally I am looking for an answer in CSS or HTML.

I'm pretty sure this could be done fairly easily in Javascript, but the client wants to make sure the phone number is formatted correctly even if Javascript is disabled (don't ask).

I want the most effective and efficient way of changing the number to what I want. If someone can figure out how to add brackets to the number (like this: (01987) 123456) as well as the space using just CSS/HTML you will immediately get marked as correct as well as my eternal gratitude.


EDIT:

I get that CSS is for design, Ive been a web developer for 15+ years. I could really do with a CSS hack to produce what I want, and explaining to the client the basics of web design is unfortunately not an option (they think they know better and I am in no position to dictate anything to them). I'm in a bit of a nightmare situation, and I need your help!

I know that content can be added to a page with CSS using content. I am aware of the ::first-letter method that @gillesc mentions in the comments. I was hoping something like this might help me.

The client uses modern browsers so a CSS3 solution would be fine.

And no, I cant change the outputted HTML.

Jimmery
  • 9,783
  • 25
  • 83
  • 157
  • Why 01987?It means first five digits? – pavel Jun 15 '15 at 10:48
  • 4
    Simple. The answer is **NO**. You can only *design* with CSS and **not program** with CSS! – Praveen Kumar Purushothaman Jun 15 '15 at 10:49
  • I'm not sure you can handle this in css without changing the html. Can you just handle the formatting on the server side before rendering? – Brian Jun 15 '15 at 10:49
  • Why don't you format it when you're binding the page? Or if this is user input, use JS or another mask plugin. – Rob Scott Jun 15 '15 at 10:50
  • You can't program with CSS but if the letter sub selectors were extended like the child one to support more than `::first-letter` and something more like `nth-letter()` then it could be done. But currently you're right, the anser is NO in pure CSS. – GillesC Jun 15 '15 at 10:51
  • Can you change the HTML at all? Something like
    01987123456
    – James King Jun 15 '15 at 10:59
  • @JamesKing: why `span`? – pavel Jun 15 '15 at 11:08
  • Also, the fact that the **client** uses modern browsers is no guarantee that the users will...something to bear in mind. – Paulie_D Jun 15 '15 at 12:18
  • http://code.tutsplus.com/tutorials/mobile-web-quick-tip-phone-number-links--mobile-7667 – Paulie_D Jun 15 '15 at 12:22
  • @Paulie_D I understand this. But the client is who I have to please here. Bad design practice? Yes. But then the client doesn't seem to care about their users, and they work under the assumption that everyone else has the same kind of computer / browser as they have. I know. Ive tried telling them, only to get shot down. – Jimmery Jun 15 '15 at 12:49

2 Answers2

9

I was interested to see if this could be done with CSS, even if it shouldn't be done! The following is quite hacky, ideally the phone number would be formatted server side or, if that isn't an option, with JavaScript.

A few caveats:

  • This requires an attribute to be added to .phone for the pseudo element to use. This may or may not be a deal breaker given that you seem to have limited access to the HTML
  • If the phone number is not in a suitable format (e.g. something like 01 987123456) it will not display correctly
  • A nasty little hack is used for IE as it doesn't calculate the width of the pseudo element correctly using ch for some reason. Credit to SW4 for this: https://stackoverflow.com/a/20541859
  • A solid background colour is required

The general idea behind this is as follows:

  • .phone
    • text-indent: 1ch; on .phone moves the whole text to the left by one character
    • .phone is set to position: relative; to allow the pseudo element to be positioned relatively to it
    • white-space: nowrap; ensures that this doesn't wrap onto a new line if there is a break in the number
  • .phone:before
    • background-color: white; masks the digits in .phone
    • border-right: 1ch solid white; hides the sixth digit in .phone, in effect this is the space
    • content: attr(data-phone); uses the data-phone attribute on .phone to populate the pseudo element with the same number
  • left: 0;, position: absolute; and top: 0; are used to position the pseudo element
  • overflow: hidden; hides any characters over the 5 character limit
  • text-indent: 0; resets text-indent: 1ch; set on .phone
  • width: 5ch; ensures that the pseudo element is only 5 characters long
  • The weird media query is the hack to target IE

Tested and working in FF 38.0.5, Chrome 43.0.2357.124 m and IE 11. Browsers not supporting the ch unit (such as Opera 12.17 and Windows Safari 5.1.7) seem to show the phone number in its natural state.

.phone {
    position: relative;
    text-indent: 1ch;
    white-space: nowrap;
}
.phone:before {
    background-color: white;
    border-right: 1ch solid white;
    content: attr(data-phone);
    display: block;
    left: 0;
    overflow: hidden;
    position: absolute;
    text-indent: 0;
    top: 0;
    width: 5ch;
}
@media screen and (min-width:0\0) and (min-resolution: +72dpi) {
    .phone:before {
        width: 5.8ch;
    }
}
<div class="phone" data-phone="01987123456">01987123456</div>

JS Fiddle: https://jsfiddle.net/scarjnb1/

Community
  • 1
  • 1
Hidden Hobbes
  • 13,893
  • 3
  • 38
  • 64
  • 1
    this is fantastic! thanks for the help and thanks for giving it a go despite the fact that it "shouldnt be done"! :) – Jimmery Jun 16 '15 at 08:09
  • 2
    @Jimmery No problem, sad to say I got a perverse pleasure out of making CSS do something it shouldn't really do! :p – Hidden Hobbes Jun 16 '15 at 08:26
1

It's not possible using CSS, just JavaScript. Then it'd be:

<div id="phone">01987123456</div>

<script>
    var el = document.getElementById('phone');
    phone.innerText = phone.innerText.replace(/^(\d{5})/, '($1) ');
</script>
pavel
  • 26,538
  • 10
  • 45
  • 61