Yes, it is possible to format dates with only CSS. This includes changing year/month/day display order, the separators between the dates, showing/hiding leading zeroes, display 4-digit years as 2-digit years (e.g. 1994 becomes '94), can be extended to include hours/minutes/seconds/etc., and even works inline within a paragraph. It allows static HTML to be reformatted later just with CSS. This provides great flexibility, doesn't require learning Javascript, and I'm using it myself to format dates on Anki cards (which use HTML and CSS).
First some limitations: it won't work on older browsers, it requires modifying the source HTML, and it requires source date leading zeros to be consistent (either always present or always absent), and it's not particularly elegant. If you already know Javascript, that's going to be a more powerful and more elegant solution.
The solution uses a flexbox to allow changing the order of the elements, and puts the date values in HTML custom attributes to be able to be read by the CSS. Click Run Code Snippet on the example below to see how day=3
, month=9
, and year=1994
is formatted with CSS into March 09, '94
.
<div class="date-wrapper">
<div class="date-year" val="1994"></div>
<div class="date-month" val="03"></div>
<div class="date-day" val="09"></div>
</div>
/* Setup for date flexbox */
.date-wrapper {
align-items: baseline;
background: #f00;
display: inline-flex;
}
.date-year,
.date-month,
.date-day {
display: inline-block;
}
/* Set date display order */
.date-year { order: 3; }
.date-month { order: 1; }
.date-day { order: 2; }
.date-suffix { order: 4; }
/* Display dates based on "val" custom attribute in HTML */
.date-year::after,
.date-month::after,
.date-day::after {
content: attr(val);
}
/* Add separators */
.date-year::before { content: ", "; }
.date-month::before { content: "★"; }
.date-day::before { content: "\00a0"; } /* \00a0 is a non-breaking space */
.date-suffix::before { content: "★"; }
/* Convert month numbers to month text */
.date-month[ val="1"]:after{ content: "January"; }
.date-month[ val="2"]:after{ content: "February"; }
.date-month[ val="3"]:after{ content: "March"; }
.date-month[ val="4"]:after{ content: "April"; }
.date-month[ val="5"]:after{ content: "May"; }
.date-month[ val="6"]:after{ content: "June"; }
.date-month[ val="7"]:after{ content: "July"; }
.date-month[ val="8"]:after{ content: "August"; }
.date-month[ val="9"]:after{ content: "September"; }
.date-month[val="10"]:after{ content: "October"; }
.date-month[val="11"]:after{ content: "November"; }
.date-month[val="12"]:after{ content: "December"; }
/* Add leading zero to days */
.date-day[val="1"]:after{ content: "01"; }
.date-day[val="2"]:after{ content: "02"; }
.date-day[val="3"]:after{ content: "03"; }
.date-day[val="4"]:after{ content: "04"; }
.date-day[val="5"]:after{ content: "05"; }
.date-day[val="6"]:after{ content: "06"; }
.date-day[val="7"]:after{ content: "07"; }
.date-day[val="8"]:after{ content: "08"; }
.date-day[val="9"]:after{ content: "09"; }
/* Display 4-digit years as 2-digit years (e.g. 1994 becomes '94) */
/* As far as I can tell, doing this fully requires 100 lines of CSS which kinda sucks */
.date-year[val="1990"]:after{ content: "'90"; }
.date-year[val="1991"]:after{ content: "'91"; }
.date-year[val="1992"]:after{ content: "'92"; }
.date-year[val="1993"]:after{ content: "'93"; }
.date-year[val="1994"]:after{ content: "'94"; }
.date-year[val="1995"]:after{ content: "'95"; }
.date-year[val="1996"]:after{ content: "'96"; }
.date-year[val="1997"]:after{ content: "'97"; }
.date-year[val="1998"]:after{ content: "'98"; }
.date-year[val="1999"]:after{ content: "'99"; }
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec iaculis lacus non risus consectetur aliquet. Duis placerat ac nulla eu
<span class="date-wrapper">
<span class="date-year" val="1994"></span>
<span class="date-month" val="3"></span>
<span class="date-day" val="9"></span>
<span class="date-suffix"></span>
</span>
lobortis. Integer vulputate, metus eget maximus pretium, nisl orci ultrices
quam, sit amet rutrum lacus neque vitae turpis.</p>
Changing display of numbers into percents is possible with the same search-and-replace technique, but since dates are finite (only 12 months and 31 days to deal with) but numbers are infinite, this is only useful when dealing with numbers in a very small range. For example, if you're only ever changing 3.59 to 3.6%, then it's trivially easy. For anything else, Javascript or other scripting will be far more elegant.
/* Display 3.59 as 3.6% */
.num-to-percent[val="3.59"]::after{ content:"3.6%"; }
<span class="num-to-percent" val="3.59"></span>