7

I searched a lot for a way to do what I want but I only found ways that I can't use.

The problem is: I want to mirror ONLY the first letter of a Wordpress Site Title.

I have this Css:

.site-title {
    font-family: fontLogo;
    font-size: 60px;
    font-weight: bold;
    line-height: 1;
    margin: 0;
    padding: 58px 0 10px;
}

and I have added this piece:

.site-title::first-letter {
    font-size: 80px;
    -moz-transform: scale(-1, 1);
    -webkit-transform: scale(-1, 1);
    -o-transform: scale(-1, 1);
    -ms-transform: scale(-1, 1);
    transform: scale(-1, 1);
}

The class is used here:

<h1 class="site-title">TheTitle</h1>

A second problem is that I CANNOT edit this line, the only thing I can do is work with the css (I tried also to type a >span> in the Title editor of WordPress without success.

The CSS actually is doing ONLY the scale of the letter, from 60px to 80px, but nothing is mirrored.

I am blocked and need a tip

rnevius
  • 26,578
  • 10
  • 58
  • 86
Gianmarco
  • 2,536
  • 25
  • 57
  • 2
    How would you know if it is mirrored, if it is a "T" letter? – LcSalazar Nov 06 '14 at 17:48
  • It isn't being mirrored. I change the letter to an "E" and it didn't work. – Ian Hazzard Nov 06 '14 at 17:51
  • Obviously LcSalazar I was trying with a custom font that is not symmetric, and by the way the original title, that I didn't put up here for clarity, begins with an "M" that is also the same if mirrored, in a standard font. – Gianmarco Nov 06 '14 at 18:02
  • If you want to add a span to the first letter of all the titles in wordpress, you can hook into [the title](http://codex.wordpress.org/Plugin_API/Filter_Reference/the_title) filter in your theme's function.php file – yoavmatchulsky Nov 06 '14 at 18:03
  • Incidentally, the CSS-generated pseudo-elements (`::before` and `::after`) require that the `content` property be set (even if only to an empty string, `content: '';`) in order to be rendered at all. – David Thomas Nov 07 '14 at 08:24
  • Also see http://stackoverflow.com/q/3433641/632951 – Pacerier Jun 30 '15 at 07:53

4 Answers4

7

According to MDN's docs on ::first-letter, you can't:

Only a small subset of all CSS properties can be used inside a declaration block of a CSS ruleset containing a selector using the ::first-letter pseudo-element:

All font properties : font, font-style, font-feature-settings, font-kerning, font-language-override, font-stretch, font-synthesis, font-variant, font-variant-alternates, font-variant-caps, font-variant-east-asian, font-variant-ligatures, font-variant-numeric, font-variant-position, font-weight, font-size, font-size-adjust, line-height and font-family.

All background properties : background-color, background-image, background-clip, background-origin, background-position, background-repeat, background-size, background-attachment, and background-blend-mode.

All margin properties: margin, margin-top, margin-right, margin-bottom, margin-left.

All padding properties: padding, padding-top, padding-right, padding-bottom, padding-left.

All border properties: the shorthands border, border-style, border-color, border-width, border- radius, border-image, and the longhands properties.

The color property.

The text-decoration, text-shadow, text-transform, letter-spacing, word-spacing (when appropriate), line-height, text-decoration-color, text-decoration-line, text-decoration-style, box-shadow, float, vertical-align (only if float is none) CSS properties.

EDIT

As an alternative, since you cannot change the HTML, you could turn the first letter into a real element, with some javascript:

JsFiddle Example

var title = document.querySelector('.site-title');
var fletter = title.innerHTML.charAt(0);
title.innerHTML = title.innerHTML.replace(fletter, '<span>'+fletter+'</span>');
LcSalazar
  • 16,524
  • 3
  • 37
  • 69
  • Awesome JS hack. +1. – Ian Hazzard Nov 06 '14 at 18:07
  • your JS is very very interesting. How about SEO? Will they like it? – Gianmarco Nov 06 '14 at 18:11
  • 1
    @Gianmarco - It's been well discussed. Some people say it will, some say it won't. There's no clear statement on that. See: http://webmasters.stackexchange.com/questions/31066/flipping-text-is-good-for-seo – LcSalazar Nov 06 '14 at 18:16
  • If you want to be sure about SEO, don't replace the first letter, just change it's appearance with ::first-letter to make it invisible and modify the JS to keep it there – vals Nov 06 '14 at 19:49
6

Only a small subset of all CSS properties can be used inside a declaration block of a CSS ruleset containing a selector using the ::first-letter pseudo-element. transform isn't currently one of them.

Read more in the Mozilla Developer Docs.

Since you're using WordPress, you can always hook into 'the_title', and prepend a <span> to the title. Something like:

function prepend_title( $title, $id = null ) {
    if ( is_front_page() ) {
        return '<span class="first-letter">' . substr($title, 0, 1) . '</span>' . $title;
    } else { return $title; }
}
add_filter( 'the_title', 'prepend_title', 10, 2 );

This will make the_title() return the title, along with a duplicate first letter wrapped in a <span>.

rnevius
  • 26,578
  • 10
  • 58
  • 86
  • mmmm very interesting. I was thinking about something similar by myself so I think we reached the same idea (you prior than me LOL). The thing that I have to figure out is WHERE and WHEN the title is used, because I need that mirroring ONLY in the h1 title in the home-page (is only for a graphical reason) – Gianmarco Nov 06 '14 at 18:14
  • man, this can be the solution, and also, If I want to flip other letters in this case I will be able to do so. – Gianmarco Nov 06 '14 at 18:18
  • Yep, it's all isolated. No JS needed. – rnevius Nov 06 '14 at 18:20
  • still worrying about SEO though. As linked by LcSalazar the "use an image of the logo or text with the flipped p. Assign an alt prop to it and as above solution, add a hidden text here as well." can be better than flipping the text? This because the company name is NOT with flipped letters, but the lettering of the logo is. – Gianmarco Nov 06 '14 at 18:24
  • @Gianmarco If you modify my code above, and wrap the final `$title` in `

    ` tags, that'll mean that the entire first-letter span is OUTSIDE of the `

    ` heading. This means that there should be absolutely no SEO impact.

    – rnevius Nov 06 '14 at 18:26
  • I am testing your code, but I think we are making a mistake. I looked in the code and found that what I really should change is this: bloginfo( 'name' ); but also I figured out that MAYBE I will be able to edit the HTML of the template. – Gianmarco Nov 06 '14 at 18:39
  • I AM able to edit the HTML, BUT, when inside the h1 tags the span is not effective in mirroring. can't understand what you said about "that'll mean that the entire first-letter span is OUTSIDE of the

    heading."

    – Gianmarco Nov 06 '14 at 18:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/64422/discussion-between-gianmarco-and-rnevius). – Gianmarco Nov 06 '14 at 19:00
3

This isn't the smoothest way and it feels a bit hacky, but I think this is what you are looking for.

I added this to the CSS and then positioned the new letter using top and left.

.site-title:after {
    content: "T";
    position: absolute;
    transform: rotateX(180deg);
}

Codepen here: http://codepen.io/supah_frank/pen/dCpmo

If you can make the container outside of the H1 position: relative it would probably help with the positioning as the new letter will be its sibling.

AndrewTet
  • 1,172
  • 8
  • 20
  • This is definitely an option, if the title isn't dynamically changing. – rnevius Nov 06 '14 at 18:04
  • Yea, as I said, it's a bit hacky and I'm not a big fan of having to hard code the letter and I'd prefer to absolute position the letter to the actual H1 and not its parent, but I can't think of an other way to do that without access to the HTML. – AndrewTet Nov 06 '14 at 18:06
  • this is flipping vertically, I am looking for a vertical mirrored. I suppose that I can do it with rotateY maybe. The fact is that: the letter goes at the end (:after) and If I use ::before it is overlapping the actual title. Using relative is not working. By the way, if I have to hard-code a letter this can be not so useful as I want (I can use a jpeg) and maybe this can be an issue for SEO because the engines will never read the whole title of the site. But thanks this is a +1 answer very interesting – Gianmarco Nov 06 '14 at 18:10
  • I've edited my question to show how you can isolate the first letter of any title using a WordPress hook. Not sure if that'll change things. – rnevius Nov 06 '14 at 18:12
0

I want to put as an answer the solution that I am using (not definitively), unfortunately using a span inside an H1 is not very straightforward so I came to this:

.firstletter {
    position:absolute;
    -moz-transform: scale(-1, 1);
    -webkit-transform: scale(-1, 1);
    -o-transform: scale(-1, 1);
    -ms-transform: scale(-1, 1);
    transform: scale(-1, 1);
}
.otherletters {
    position:relative;
    left:58px;
}

this is the CSS part that is interesting, NOTE the "absolute" position for the first letter (that should be mirrored), this is necessary otherwise (BUT I DON'T KNOW WHY, if anyone knows...) it will not be mirored. After that I need to put a relative positioned span. Unfortunately is relative to the end of the last "inline" or "relative" element, not the end of our "absolute" span. For this reason I move the following letters to the right about 58px (it seems quite ok visually).

<h1 class="site-title">
    <?php 
    $name = get_bloginfo('name','raw');
    echo '<span class="firstletter">' . substr($name, 0, 1) . '</span><span class="otherletters">' . substr($name,1).'</span>'; ?>
</h1>

this is the PHP of the header, you can see the two different span tags.

For the same problem I encountered, all the solutions given by my fellows friends LcSalazar, rnevius will simply not work. The code I posted IS working, but I don't like that I have to put an hardcoded "58px" that is reached after several tests because if I change the smallest thing in the css this gap can be "transformed" to something wrong.

By now I would like to be able to calculate the width of a span, to exactly position the second.

Gianmarco
  • 2,536
  • 25
  • 57