Est-il possible d'appliquer CSS à la moitié d'un caractère?

2819

Ce que je recherche:

Une façon de coiffer une MOITIÉ d'un personnage. (Dans ce cas, la moitié de la lettre est transparente)

Ce que j'ai actuellement recherché et essayé (sans chance):

  • Méthodes de stylisation de la moitié d'un caractère / d'une lettre
  • Styliser une partie d'un caractère avec CSS ou JavaScript
  • Appliquer CSS à 50% d'un caractère

Voici un exemple de ce que j'essaie d'obtenir.

X

Existe-t-il une solution CSS ou JavaScript pour cela, ou vais-je devoir recourir à des images? Je préférerais ne pas suivre la route des images car ce texte finira par être généré dynamiquement.


MISE À JOUR:

Étant donné que beaucoup ont demandé pourquoi je voudrais jamais styliser la moitié d'un personnage, c'est pourquoi. Ma ville avait récemment dépensé 250 000 $ pour définir une nouvelle «marque» pour elle-même. Ce logo est ce qu'ils ont créé. Beaucoup de gens se sont plaints de la simplicité et du manque de créativité et continuent de le faire. Mon objectif était de proposer ce site Web comme une blague. Tapez «Halifax» et vous verrez ce que je veux dire.

Mathew MacLean
la source
1
Les commentaires ne sont pas pour une discussion approfondie; cette conversation a été déplacée vers le chat .
Yvette
6
Ils demandaient "pourquoi" parce qu'ils voulaient savoir pourquoi vous utiliseriez CSS et non SVG ou un éditeur d'images. Rien à voir avec les décisions commerciales concernant leur logo. Selon votre lien vers leur logo, pourquoi n'avez-vous pas simplement recadré le X?
user9993
1
Je ne peux pas me plaindre de ce logo. Tellement mieux que ce sanglant phare.
Parapluie
@Parapluie Je serais d'accord!
Mathew MacLean

Réponses:

2941

Maintenant sur GitHub en tant que plugin!

entrez la description de l'image ici N'hésitez pas à bifurquer et à vous améliorer.

Démo | Télécharger Zip | Half-Style.com (redirige vers GitHub)


  • CSS pur pour un seul caractère
  • JavaScript utilisé pour l'automatisation sur du texte ou plusieurs caractères
  • Préserve l'accessibilité du texte pour les lecteurs d'écran pour les aveugles ou les malvoyants

Partie 1: Solution de base

Demi-style sur le texte

Démo: http://jsfiddle.net/arbel/pd9yB/1694/


Cela fonctionne sur n'importe quel texte dynamique ou sur un seul caractère et est entièrement automatisé. Tout ce que vous avez à faire est d'ajouter une classe sur le texte cible et le reste est pris en charge.

De plus, l'accessibilité du texte original est préservée pour les lecteurs d'écran pour les aveugles ou les malvoyants.

Explication pour un seul caractère:

CSS pur. Tout ce que vous devez faire est d'appliquer une .halfStyleclasse à chaque élément qui contient le caractère que vous souhaitez mettre en demi-style.

Pour chaque élément span contenant le caractère, vous pouvez créer un attribut de données, par exemple ici data-content="X", et sur le pseudo-élément utiliser content: attr(data-content);pour que la .halfStyle:beforeclasse soit dynamique et vous n'aurez pas besoin de le coder en dur pour chaque instance.

Explication pour tout texte:

Ajoutez simplement une textToHalfStyleclasse à l'élément contenant le texte.


// jQuery for automated mode
jQuery(function($) {
    var text, chars, $el, i, output;

    // Iterate over all class occurences
    $('.textToHalfStyle').each(function(idx, el) {
    $el = $(el);
    text = $el.text();
    chars = text.split('');

    // Set the screen-reader text
    $el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + text + '</span>');

    // Reset output for appending
    output = '';

    // Iterate over all chars in the text
    for (i = 0; i < chars.length; i++) {
        // Create a styled element for each character and append to container
        output += '<span aria-hidden="true" class="halfStyle" data-content="' + chars[i] + '">' + chars[i] + '</span>';
    }

    // Write to DOM only once
    $el.append(output);
  });
});
.halfStyle {
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    color: black; /* or transparent, any color */
    overflow: hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
}

.halfStyle:before {
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow: hidden;
    color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>Single Characters:</p>
<span class="halfStyle" data-content="X">X</span>
<span class="halfStyle" data-content="Y">Y</span>
<span class="halfStyle" data-content="Z">Z</span>
<span class="halfStyle" data-content="A">A</span>

<hr/>
<p>Automated:</p>

<span class="textToHalfStyle">Half-style, please.</span>

( Démo JSFiddle )


Partie 2: Solution avancée - Parties gauche et droite indépendantes

Demi-style sur le texte - avancé - Avec l'ombre du texte

Avec cette solution, vous pouvez styliser les parties gauche et droite, individuellement et indépendamment .

Tout est pareil, seul un CSS plus avancé fait la magie.

( Démo JSFiddle )



Partie 3: Mix-Match et améliorez

Maintenant que nous savons ce qui est possible, créons quelques variantes.


- Demi-pièces horizontales

  • Sans ombre de texte:

    Demi-parties horizontales - pas d'ombre de texte

  • Possibilité d'ombre de texte pour chaque demi-partie indépendamment:

    halfStyle - Demi-parties horizontales - avec ombre de texte

( Démo JSFiddle )



-Vertical 1/3 Parts

  • Sans ombre de texte:

    halfStyle - Vertical 1/3 Parts - Pas d'ombre de texte

  • Possibilité d'ombre de texte pour chaque 1/3 partie indépendamment:

    halfStyle - Vertical 1/3 Parts - Avec texte Shadow

( Démo JSFiddle )



-Horizontal 1/3 pièces

  • Sans ombre de texte:

    halfStyle - Horizontal 1/3 Parts - Pas d'ombre de texte

  • Possibilité d'ombre de texte pour chaque 1/3 partie indépendamment:

    halfStyle - Horizontal 1/3 Parts - Avec texte Shadow

( Démo JSFiddle )



-HalfStyle Improvement Par @KevinGranger

halfStyle - KevinGranger

( Démo JSFiddle )



-PeelingStyle amélioration de HalfStyle par @SamTremaine

halfStyle - SamTremaine

( Démo JSFiddle et sur samtremaine.co.uk )



Partie 4: Prêt pour la production

Différents ensembles de styles demi-style personnalisés peuvent être utilisés sur les éléments souhaités sur la même page. Vous pouvez définir plusieurs jeux de styles et indiquer au plugin lequel utiliser.

Le plugin utilise l'attribut data data-halfstyle="[-CustomClassName-]"sur les .textToHalfStyleéléments cibles et effectue automatiquement toutes les modifications nécessaires.

Donc, simplement sur l'élément contenant le texte, ajoutez la textToHalfStyleclasse et l'attribut data data-halfstyle="[-CustomClassName-]". Le plugin fera le reste du travail.

halfStyle - Multiple sur la même page

De plus, les définitions de classe des jeux de styles CSS correspondent à la [-CustomClassName-]partie mentionnée ci-dessus et sont chaînées .halfStyle, nous aurons donc.halfStyle.[-CustomClassName-]

jQuery(function($) {
    var halfstyle_text, halfstyle_chars, $halfstyle_el, halfstyle_i, halfstyle_output, halfstyle_style;

    // Iterate over all class occurrences
    $('.textToHalfStyle').each(function(idx, halfstyle_el) {
        $halfstyle_el = $(halfstyle_el);
        halfstyle_style = $halfstyle_el.data('halfstyle') || 'hs-base';
        halfstyle_text = $halfstyle_el.text();
        halfstyle_chars = halfstyle_text.split('');

        // Set the screen-reader text
        $halfstyle_el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + halfstyle_text + '</span>');

        // Reset output for appending
        halfstyle_output = '';

        // Iterate over all chars in the text
        for (halfstyle_i = 0; halfstyle_i < halfstyle_chars.length; halfstyle_i++) {
            // Create a styled element for each character and append to container
            halfstyle_output += '<span aria-hidden="true" class="halfStyle ' + halfstyle_style + '" data-content="' + halfstyle_chars[halfstyle_i] + '">' + halfstyle_chars[halfstyle_i] + '</span>';
        }

        // Write to DOM only once
        $halfstyle_el.append(halfstyle_output);
    });
});
/* start half-style hs-base */

.halfStyle.hs-base {
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    overflow: hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
    color: #000; /* for demo purposes */
}

.halfStyle.hs-base:before {
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    pointer-events: none; /* so the base char is selectable by mouse */
    overflow: hidden;
    color: #f00; /* for demo purposes */
}

/* end half-style hs-base */


/* start half-style hs-horizontal-third */

.halfStyle.hs-horizontal-third { /* base char and also the bottom 1/3 */
    position: relative;
    display: inline-block;
    font-size: 80px; /* or any font size will work */
    color: transparent;
    overflow: hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
    color: #f0f;
    text-shadow: 2px 2px 0px #0af; /* for demo purposes */
}

.halfStyle.hs-horizontal-third:before { /* creates the top 1/3 */
    display: block;
    z-index: 2;
    position: absolute;
    top: 0;
    height: 33.33%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow: hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #f00; /* for demo purposes */
    text-shadow: 2px -2px 0px #fa0; /* for demo purposes */
}

.halfStyle.hs-horizontal-third:after { /* creates the middle 1/3 */
    display: block;
    position: absolute;
    z-index: 1;
    top: 0;
    height: 66.66%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow: hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #000; /* for demo purposes */
    text-shadow: 2px 2px 0px #af0; /* for demo purposes */
}

/* end half-style hs-horizontal-third */


/* start half-style hs-PeelingStyle, by user SamTremaine on Stackoverflow.com */

.halfStyle.hs-PeelingStyle {
  position: relative;
  display: inline-block;
  font-size: 68px;
  color: rgba(0, 0, 0, 0.8);
  overflow: hidden;
  white-space: pre;
  transform: rotate(4deg);
  text-shadow: 2px 1px 3px rgba(0, 0, 0, 0.3);
}

.halfStyle.hs-PeelingStyle:before { /* creates the left part */
  display: block;
  z-index: 1;
  position: absolute;
  top: -0.5px;
  left: -3px;
  width: 100%;
  content: attr(data-content);
  overflow: hidden;
  pointer-events: none;
  color: #FFF;
  transform: rotate(-4deg);
  text-shadow: 0px 0px 1px #000;
}

/* end half-style hs-PeelingStyle */


/* start half-style hs-KevinGranger, by user KevinGranger on StackOverflow.com*/

.textToHalfStyle.hs-KevinGranger {
  display: block;
  margin: 200px 0 0 0;
  text-align: center;
}

.halfStyle.hs-KevinGranger {
  font-family: 'Libre Baskerville', serif;
  position: relative;
  display: inline-block;
  width: 1;
  font-size: 70px;
  color: black;
  overflow: hidden;
  white-space: pre;
  text-shadow: 1px 2px 0 white;
}

.halfStyle.hs-KevinGranger:before {
  display: block;
  z-index: 1;
  position: absolute;
  top: 0;
  width: 50%;
  content: attr(data-content); /* dynamic content for the pseudo element */
  overflow: hidden;
  color: white;
}

/* end half-style hs-KevinGranger
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-base">Half-style, please.</span>
</p>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-horizontal-third">Half-style, please.</span>
</p>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-PeelingStyle">Half-style, please.</span>
</p>
<p style="background-color:#000;">
    <span class="textToHalfStyle" data-halfstyle="hs-KevinGranger">Half-style, please.</span>
</p>

( Démo JSFiddle )

Arbel
la source
Les commentaires ne sont pas pour une discussion approfondie; cette conversation a été déplacée vers le chat .
Yvette
7
C'est très cool. Il convient de noter que cette technique casse les CSS de retour à la ligne, d'espace blanc et d'espacement des caractères.
Andrew Ensley
2
Ravi de voir que nous avons
bouclé la boucle
488

entrez la description de l'image ici


Je viens de terminer le développement du plugin et il est disponible pour tout le monde! J'espère que vous apprécierez.

Voir le projet sur GitHub - Voir le site Web du projet . (afin que vous puissiez voir tous les styles séparés)

Usage

Tout d'abord, assurez-vous que la jQuerybibliothèque est incluse. La meilleure façon d'obtenir la dernière version de jQuery est de mettre à jour votre balise head avec:

<script src="http://code.jquery.com/jquery-latest.min.js"></script>

Après avoir téléchargé les fichiers, assurez-vous de les inclure dans votre projet:

<link rel="stylesheet" type="text/css" href="css/splitchar.css">
<script type="text/javascript" src="js/splitchar.js"></script>

Marquage

Tout ce que vous avez à faire est d'attribuer la classe splitchar, suivi du style souhaité à l'élément qui enveloppe votre texte. par exemple

<h1 class="splitchar horizontal">Splitchar</h1>

Après tout cela, assurez-vous d'appeler la fonction jQuery dans votre fichier prêt pour le document comme ceci:

$(".splitchar").splitchar();

Personnalisation

Afin de rendre le texte exactement comme vous le souhaitez, tout ce que vous avez à faire est d'appliquer votre design comme ceci:

.horizontal { /* Base CSS - e.g font-size */ }
.horizontal:before { /* CSS for the left half */ }
.horizontal:after { /* CSS for the right half */ }


C'est ça! Maintenant, le Splitcharplugin est prêt. Plus d'informations à ce sujet sur http://razvanbalosin.com/Splitchar.js/ .

Razvan B.
la source
À l'heure actuelle, votre solution est la plus simple à implémenter pour plusieurs caractères, mais toujours pas à 100%.
Mathew MacLean
@MathewMacLean emisfera doit avoir la réponse, non?
mttdbrd
3
Cela a des problèmes avec l'habillage du texte qui est présenté même dans le dernier violon. Lorsqu'un caractère se termine, il se divise essentiellement en deux. Cela devrait être une solution triviale, cependant.
BoltClock
16
Ne dépendez pas de jquery-latest.min.js, cela peut faire casser vos sites sans avertissement si jQuery est mis à jour et le plugin ne fonctionne pas avec le plus récent. Au lieu de cela: utilisez une version spécifique et vérifiez la compatibilité lors de la mise à jour.
Niels Bom
2
Vous voudrez peut-être modifier votre réponse pour ne pas suggérer d'utiliser jquery-latest.js. Comme l'a mentionné @NielsBom, par le passé, il pouvait endommager votre site lors de sa mise à jour. Depuis juillet 2014, il ne le fera plus, mais c'est parce qu'il est verrouillé à la version 1.11.1 et ne sera plus jamais mis à jour.
Code inutile
237

Edit (oct 2017): background-clipou plutôt background-image optionssont maintenant pris en charge par tous les principaux navigateurs: CanIUse

Oui, vous pouvez le faire avec un seul caractère et un seul CSS.

Webkit (et Chrome) uniquement, cependant:

http://jsbin.com/rexoyice/1/

h1 {
  display: inline-block;
  margin: 0; /* for demo snippet */
  line-height: 1em; /* for demo snippet */
  font-family: helvetica, arial, sans-serif;
  font-weight: bold;
  font-size: 300px;
  background: linear-gradient(to right, #7db9e8 50%,#1e5799 50%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
<h1>X</h1>

Visuellement, tous les exemples qui utilisent deux caractères (que ce soit via JS, des pseudo-éléments CSS ou simplement HTML) semblent bien, mais notez que tout cela ajoute du contenu au DOM qui peut entraîner l'accessibilité - ainsi que la sélection / coupe / coller des problèmes.

DA.
la source
34
@MathewMacLean nos travaux seraient tellement plus faciles si seulement IE mourrait et Firefox commençait à utiliser Webkit. :)
DA.
48
WebKit a une histoire de rendu de bogues qui sont presque des niveaux bizarres IE6 / IE7 (vous pourriez même dire que Safari et Chrome sont l'IE6 du Web moderne), et se comportent de manière qui s'écartent de la norme sans raison particulière. IE a été beaucoup mieux depuis la version 9, donc bien que les anciennes versions devraient déjà mourir, je ne vois aucune raison de la haine pour ses versions récentes. Et je ne vois certainement pas pourquoi les gens soutiennent l'idée d'une monoculture WebKit / Blink (les commentaires ici sont probablement en plaisantant, mais j'ai entendu parler de gens qui y croient sérieusement).
BoltClock
3
Cela étant dit, background-clip: textc'est super génial et ils devraient le considérer (ou quelque chose de similaire text-decoration-background) pour un module de niveau 4.
BoltClock
2
Ouais, je serais plus heureux si blink / webkit mourait et que les moteurs de rendu FF + IE modernes survivaient que l'inverse. Ce qui ne veut pas dire que le reste du chrome n'est pas agréable, juste que son rendu est à peu près le pire du groupe de nos jours.
Eamon Nerbonne
2
C'est une solution beaucoup plus propre que les bibliothèques hacky ci-dessus, devrait être une réponse acceptée car les dégradés de texte sont utilisables de nos jours.
mystrdat
160

Exemple


JSFiddle DEMO

Nous le ferons en utilisant uniquement des pseudo-sélecteurs CSS!

Cette technique fonctionnera avec du contenu généré dynamiquement et différentes tailles et largeurs de police.

HTML:

<div class='split-color'>Two is better than one.</div>

CSS:

.split-color > span {
    white-space: pre-line;
    position: relative;
    color: #409FBF;
}

.split-color > span:before {
    content: attr(data-content);
    pointer-events: none;  /* Prevents events from targeting pseudo-element */
    position: absolute;
    overflow: hidden;
    color: #264A73;
    width: 50%;
    z-index: 1;
}

Pour encapsuler la chaîne générée dynamiquement, vous pouvez utiliser une fonction comme celle-ci:

// Wrap each letter in a span tag and return an HTML string
// that can be used to replace the original text
function wrapString(str) {
  var output = [];
  str.split('').forEach(function(letter) {
    var wrapper = document.createElement('span');
    wrapper.dataset.content = wrapper.innerHTML = letter;

    output.push(wrapper.outerHTML);
  });

  return output.join('');
}

// Replace the original text with the split-color text
window.onload = function() {
    var el  = document.querySelector('.split-color'),
        txt = el.innerHTML;

    el.innerHTML = wrapString(txt);
}
wvandaal
la source
C'est bien, mais le seul problème est que le contenu sera dynamique.
Mathew MacLean
Les résultats varient en fonction de la police utilisée. De plus, le calcul de la largeur semble être un problème.
j08691
@MathewMacLean hmm, votre contenu ne serait-il qu'un seul caractère? Sinon, voudriez-vous que chaque personnage ait le même effet de couleur partagée ou seulement certains (c'est-à-dire le premier)?
wvandaal
1
@MathewMacLean, vous pouvez écrire une fonction de boucle simple dans JS pour effectuer le wrapping. Je l'ajoute à ma réponse maintenant.
wvandaal
1
@MathewMacLean D'où vient le texte? wvandaal a raison, vous pouvez envelopper le texte vous-même.
mttdbrd
96

Cela peut ne pas être pertinent, peut-être pas, mais il y a quelque temps, j'ai créé une fonction jQuery qui fait la même chose, mais horizontalement.

Je l'ai appelé "Strippex" Pour 'stripe' + 'text', démo: http://cdpn.io/FcIBg

Je ne dis pas que c'est la solution à tous les problèmes, mais j'ai déjà essayé d'appliquer CSS à la moitié d'un personnage, mais horizontalement, donc l'idée est la même, la réalisation peut être horrible, mais ça marche.

Ah, et le plus important, je me suis amusé à le créer!

entrez la description de l'image ici

LukyVj
la source
2
@Luky Vj: Ce compte est-il le vôtre? Vous voudrez peut-être consolider toutes vos publications dans un seul compte afin de ne pas rencontrer de barrages routiers en essayant de modifier vos propres publications.
BoltClock
Ouais, en fait, j'ai d'abord posté avec mon ancien premier compte .. Et j'ai dû ajouter une image, et je n'étais pas assez populaire pour poster mon image .. Mais vous avez raison, je vais la réparer dès que possible !
LukyVj
1
@LukyVj: Vous pouvez fusionner vos comptes en suivant les instructions ici: stackoverflow.com/help/merging-accounts
BoltClock
1
@LukyVj J'ai mis à jour votre fonction en ajoutant pointer-events:noneà &:nth-child(2)- &:nth-child(5). Ainsi, le texte ne peut être mis en surbrillance qu'une seule fois et vous n'en obtenez qu'une seule copie. Vous pouvez le voir ici: codepen.io/anon/pen/upLaj
Mathew MacLean
74

Si cela vous intéresse, alors le Glitch de Lucas Bebber est un effet très similaire et super cool:

entrez la description de l'image ici

Créé à l'aide d'un simple mixin SASS tel que

.example-one {
  font-size: 100px;
  @include textGlitch("example-one", 17, white, black, red, blue, 450, 115);
}

Plus de détails sur les astuces CSS de Chris Coyer et la page Codepen de Lucas Bebber

Ruskin
la source
74

Voici une implémentation moche dans canvas. J'ai essayé cette solution, mais les résultats sont pires que ce à quoi je m'attendais, alors la voici quand même.

Exemple de toile

$("div").each(function() {
  var CHARS = $(this).text().split('');
  $(this).html("");
  $.each(CHARS, function(index, char) {
    var canvas = $("<canvas />")
      .css("width", "40px")
      .css("height", "40px")
      .get(0);
    $("div").append(canvas);
    var ctx = canvas.getContext("2d");
    var gradient = ctx.createLinearGradient(0, 0, 130, 0);
    gradient.addColorStop("0", "blue");
    gradient.addColorStop("0.5", "blue");
    gradient.addColorStop("0.51", "red");
    gradient.addColorStop("1.0", "red");
    ctx.font = '130pt Calibri';
    ctx.fillStyle = gradient;
    ctx.fillText(char, 10, 130);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Example Text</div>

Fiambre
la source
1
BTW, vous pouvez également utiliser 0.5pour l'arrêt de la couleur rouge.
Brosse à dents
62

Le plus près que je peux obtenir:

$(function(){
  $('span').width($('span').width()/2);
  $('span:nth-child(2)').css('text-indent', -$('span').width());
});
body{
  font-family: arial;
}
span{
  display: inline-block;
  overflow: hidden;
}
span:nth-child(2){
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>X</span><span>X</span>

Démo: http://jsfiddle.net/9wxfY/2/

Voici une version qui n'utilise qu'une seule plage: http://jsfiddle.net/9wxfY/4/

Prisonnier
la source
1
$('span').width()renvoie simplement la largeur de la première travée qu'il trouve; ce devrait être quelque chose que vous avez fait pour chaque paire. Ce qui me donne une idée ...
Pointy
Ceci est assez similaire à l'exemple d'epascarello trouvé sur jsfiddle.net/9WWsd. Comme je lui ai dit, votre exemple est un pas dans la bonne direction, mais ce serait un cauchemar à utiliser à plus grande échelle.
Mathew MacLean,
@MathewMacLean, je n'ai pas vu ça. Pourquoi serait-ce un cauchemar? Que diriez-vous de ceci: jsfiddle.net/9wxfY/4
Prisonnier
Lorsque vous allez implémenter plusieurs caractères, cela pose des problèmes.
Mathew MacLean
@MathewMacLean c'est là que le fabuleux Lettering.JS entre en jeu.
Pointy
53

Entrez la description de l'image ici

Je viens de jouer avec la solution de @ Arbel:

var textToHalfStyle = $('.textToHalfStyle').text();
var textToHalfStyleChars = textToHalfStyle.split('');
$('.textToHalfStyle').html('');
$.each(textToHalfStyleChars, function(i,v){
    $('.textToHalfStyle').append('<span class="halfStyle" data-content="' + v + '">' + v + '</span>');
});
body{
    background-color: black;
}
.textToHalfStyle{
    display:block;
    margin: 200px 0 0 0;
    text-align:center;
}
.halfStyle {
    font-family: 'Libre Baskerville', serif;
    position:relative;
    display:inline-block;
    width:1;
    font-size:70px;
    color: black;
    overflow:hidden;
    white-space: pre;
    text-shadow: 1px 2px 0 white;
}
.halfStyle:before {
    display:block;
    z-index:1;
    position:absolute;
    top:0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<span class="textToHalfStyle">Dr. Jekyll and M. Hide</span>

Shipow
la source
4
Je viens de jouer avec la solution @Arbel Quelles sont les différences avec la solution d'Arbel? Il est difficile de voir si vous avez seulement copié-collé du code ou si vous l'avez amélioré.
AL
43

Une autre solution CSS uniquement (bien que l'attribut data soit nécessaire si vous ne voulez pas écrire de CSS spécifique à une lettre). Celui-ci fonctionne plus dans tous les domaines (Testé IE 9/10, Chrome dernier et FF dernier)

span {
  position: relative;
  color: rgba(50,50,200,0.5);
}

span:before {
  content: attr(data-char);
  position: absolute;
  width: 50%;
  overflow: hidden;
  color: rgb(50,50,200);
}
<span data-char="X">X</span>

MStrutt
la source
38

Solution CSS et jQuery limitée

Je ne sais pas à quel point cette solution est élégante, mais elle coupe tout exactement de moitié: http://jsfiddle.net/9wxfY/11/

Sinon, j'ai créé une bonne solution pour vous ... Tout ce que vous avez à faire est d'avoir ceci pour votre HTML:

Jetez un œil à cette édition la plus récente et la plus précise du 13/06/2016: http://jsfiddle.net/9wxfY/43/

Quant au CSS, il est très limité ... Il suffit de l'appliquer à :nth-child(even)

$(function(){
  var $hc = $('.half-color');
  var str = $hc.text();
  $hc.html("");

  var i = 0;
  var chars;
  var dupText;

  while(i < str.length){
    chars = str[i];
    if(chars == " ") chars = "&nbsp;";
    dupText = "<span>" + chars + "</span>";

    var firstHalf = $(dupText);
    var secondHalf = $(dupText);

    $hc.append(firstHalf)
    $hc.append(secondHalf)

    var width = firstHalf.width()/2;

    firstHalf.width(width);
    secondHalf.css('text-indent', -width);

    i++;
  }
});
.half-color span{
  font-size: 2em;
  display: inline-block;
  overflow: hidden;
}
.half-color span:nth-child(even){
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="half-color">This is a sentence</div>

Ajuster
la source
Cela a les mêmes problèmes que les autres. Cela commence à devenir désordonné lorsque vous essayez de le faire avec plus d'un personnage.
Mathew MacLean
@MathewMacLean Je sais :( vu ça aussi.
Y
@MathewMacLean l'a corrigé, mais ne savez pas à quel point le JQuery est maintenant propre. Jetez un oeil
Adjit
@MathewMacLean ajoutant à la version webkit des choses que vous pourriez utiliser une solution comme celle-ci: jsfiddle.net/wLkVt/1
Adjit
@MathewMacLean Correction de l'erreur dans mon script. La raison de l'erreur était que je prenais tout le temps la largeur du tout premier élément, au lieu de la largeur des lettres.
Ajuster le
30
.halfStyle {
    position:relative;
    display:inline-block;
    font-size:68px; /* or any font size will work */
    color: rgba(0,0,0,0.8); /* or transparent, any color */
    overflow:hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
    transform:rotate(4deg);
    -webkit-transform:rotate(4deg);
    text-shadow:2px 1px 3px rgba(0,0,0,0.3);
}
.halfStyle:before {
    display:block;
    z-index:1;
    position:absolute;
    top:-0.5px;
    left:-3px;
    width: 100%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    color: white;
    transform:rotate(-4deg);
    -webkit-transform:rotate(-4deg);
    text-shadow:0 0 1px black;

}

http://experimental.samtremaine.co.uk/half-style/

Vous pouvez contraindre ce code à faire toutes sortes de choses intéressantes - ce n'est qu'une implémentation que mon associé et moi avons proposée hier soir.

Sam Tremaine
la source
27

Une belle solution WebKit uniquement qui tire parti du background-clip: textsupport: http://jsfiddle.net/sandro_paganotti/wLkVt/

span{
   font-size: 100px;
   background: linear-gradient(to right, black, black 50%, grey 50%, grey);
   -webkit-background-clip: text;
   -webkit-text-fill-color: transparent;
}
Sandro Paganotti
la source
24

Que diriez-vous de quelque chose comme ça pour un texte plus court?

Cela pourrait même fonctionner pour un texte plus long si vous faisiez quelque chose avec une boucle, en répétant les caractères avec JavaScript. Quoi qu'il en soit, le résultat est quelque chose comme ceci:

Est-il possible d'appliquer CSS à la moitié d'un caractère?

p.char {
  position: relative;
  display: inline-block;
  font-size: 60px;
  color: red;
}

p.char:before {
  position: absolute;
  content: attr(char);
  width: 50%;
  overflow: hidden;
  color: black;
}
<p class="char" char="S">S</p>
<p class="char" char="t">t</p>
<p class="char" char="a">a</p>
<p class="char" char="c">c</p>
<p class="char" char="k">k</p>
<p class="char" char="o">o</p>
<p class="char" char="v">v</p>
<p class="char" char="e">e</p>
<p class="char" char="r">r</p>
<p class="char" char="f">f</p>
<p class="char" char="l">l</p>
<p class="char" char="o">o</p>
<p class="char" char="w">w</p>

Alireza
la source
23

FWIW, voici mon point de vue sur cela en le faisant uniquement avec CSS: http://codepen.io/ricardozea/pen/uFbts/

Plusieurs notes:

  • La principale raison pour laquelle j'ai fait cela était de me tester et de voir si j'étais capable de styliser la moitié d'un personnage tout en fournissant une réponse significative à l'OP.

  • Je suis conscient que ce n'est pas une solution idéale ou la plus évolutive et les solutions proposées par les gens ici sont bien meilleures pour des scénarios "du monde réel".

  • Le code CSS que j'ai créé est basé sur les premières pensées qui me sont venues à l'esprit et sur ma propre approche personnelle du problème.

  • Ma solution ne fonctionne que sur les caractères symétriques, comme X, A, O, M. ** Elle ne fonctionne pas sur les caractères asymétriques comme B, C, F, K ou les lettres minuscules.

  • ** CEPENDANT, cette approche crée des «formes» très intéressantes avec des caractères asymétriques. Essayez de changer le X en K ou en minuscule comme un h ou un p dans le CSS :)

HTML

<span class="half-letter"></span>

SCSS

.half-character { 
  display: inline-block;
  font: bold 350px/.8 Arial;
  position: relative;

  &:before, &:after {
    content: 'X'; //Change character here
    display: inline-block;
    width: 50%;
    overflow: hidden;
    color: #7db9e8;
  }
  &:after {
    position: absolute;
    top: 0;
    left: 50%;
    color: #1e5799;
    transform: rotateY(-180deg);
  }
}
Ricardo Zea
la source
17

Vous pouvez également le faire en utilisant SVG, si vous le souhaitez:

var title = document.querySelector('h1'),
    text = title.innerHTML,
    svgTemplate = document.querySelector('svg'),
    charStyle = svgTemplate.querySelector('#text');

svgTemplate.style.display = 'block';

var space = 0;

for (var i = 0; i < text.length; i++) {
  var x = charStyle.cloneNode();
  x.textContent = text[i];
  svgTemplate.appendChild(x);
  x.setAttribute('x', space);
  space += x.clientWidth || 15;
}

title.innerHTML = '';
title.appendChild(svgTemplate);
<svg style="display: none; height: 100px; width: 100%" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
    <defs id="FooDefs">
        <linearGradient id="MyGradient" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="50%" stop-color="blue" />
            <stop offset="50%" stop-color="red" />
        </linearGradient>
    </defs>
    <text y="50%" id="text" style="font-size: 72px; fill: url(#MyGradient)"></text>
</svg>

<h1>This is not a solution X</h1>

http://codepen.io/nicbell/pen/jGcbq

Nic Bell
la source
16

Ceci peut être réalisé avec juste le :beforesélecteur CSS et content property value.

.halfed, .halfed1 {
  float: left;
}

.halfed, .halfed1 {
  font-family: arial;
  font-size: 300px;
  font-weight: bolder;
  width: 200px;
  height: 300px;
  position: relative; /* To help hold the content value within */
  overflow: hidden;
  color: #000;
}




.halfed:before, .halfed1:before   {
  width: 50%; /* How much we'd like to show */
  overflow: hidden; /* Hide what goes beyond our dimension */  
  content: 'X'; /* Halfed character */
  height: 100%;
  position: absolute;
  color: #28507D;

}



/* For Horizontal cut off */ 

.halfed1:before   {
  width: 100%;
  height: 55%;
  
}
<div class="halfed"> X </div>

<div class="halfed1"> X </div>

>> Voir sur jsFiddle

Geek élégant
la source
8

Vous pouvez utiliser le code ci-dessous. Ici, dans cet exemple, j'ai utilisé une h1balise et ajouté un attribut data-title-text="Display Text"qui apparaîtra avec un texte de couleur différente sur h1l'élément de texte de la balise, ce qui donne un texte semi-coloré comme indiqué dans l'exemple ci-dessous

entrez la description de l'image ici

body {
  text-align: center;
  margin: 0;
}

h1 {
  color: #111;
  font-family: arial;
  position: relative;
  font-family: 'Oswald', sans-serif;
  display: inline-block;
  font-size: 2.5em;
}

h1::after {
  content: attr(data-title-text);
  color: #e5554e;
  position: absolute;
  left: 0;
  top: 0;
  clip: rect(0, 1000px, 30px, 0);
}
<h1 data-title-text="Display Text">Display Text</h1>

GSB
la source
5

Juste pour le record de l'histoire!

J'ai trouvé une solution pour mon propre travail il y a 5-6 ans, qui est Gradext (javascript pur et css pur, pas de dépendance).

L'explication technique est que vous pouvez créer un élément comme celui-ci:

<span>A</span>

Maintenant, si vous voulez créer un dégradé sur du texte, vous devez créer plusieurs couches, chacune colorée individuellement et le spectre créé illustrera l'effet de dégradé.

par exemple regardez ceci est le mot lorem à l' intérieur d'un <span>et provoquera un effet de gradient horizontal ( consultez les exemples ):

 <span data-i="0" style="color: rgb(153, 51, 34);">L</span>
 <span data-i="1" style="color: rgb(154, 52, 35);">o</span>
 <span data-i="2" style="color: rgb(155, 53, 36);">r</span>
 <span data-i="3" style="color: rgb(156, 55, 38);">e</span>
 <span data-i="4" style="color: rgb(157, 56, 39);">m</span>

et vous pouvez continuer à faire ce modèle pendant longtemps et un long paragraphe également.

entrez la description de l'image ici

Mais!

Et si vous souhaitez créer un effet de dégradé vertical sur les textes?

Ensuite, il existe une autre solution qui pourrait être utile. Je décrirai en détail.

En supposant notre premier à <span>nouveau. mais le contenu ne doit pas être les lettres individuellement; le contenu doit être tout le texte, et maintenant nous allons copier le même <span>encore et encore (nombre de travées définira la qualité de votre dégradé, plus étendue, un meilleur résultat, mais la mauvaise performance). jetez un oeil à ceci:

<span data-i="6" style="color: rgb(81, 165, 39); overflow: hidden; height: 11.2px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span>
<span data-i="7" style="color: rgb(89, 174, 48); overflow: hidden; height: 12.8px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span>
<span data-i="8" style="color: rgb(97, 183, 58); overflow: hidden; height: 14.4px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span>
<span data-i="9" style="color: rgb(105, 192, 68); overflow: hidden; height: 16px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span>
<span data-i="10" style="color: rgb(113, 201, 78); overflow: hidden; height: 17.6px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span>
<span data-i="11" style="color: rgb(121, 210, 88); overflow: hidden; height: 19.2px;">Lorem ipsum dolor sit amet, tincidunt ut laoreet dolore magna aliquam erat volutpat.</span>

entrez la description de l'image ici

Encore une fois, mais!

que faire si vous voulez que ces effets de dégradé se déplacent et en créent une animation?

eh bien, il y a aussi une autre solution. Vous devriez certainement vérifier animation: trueou même la .hoverable()méthode qui conduira à un dégradé pour commencer en fonction de la position du curseur! (semble cool xD)

entrez la description de l'image ici

c'est simplement ainsi que nous créons des dégradés (linéaires ou radiaux) sur les textes. Si vous avez aimé l'idée ou souhaitez en savoir plus, vous devriez vérifier les liens fournis.


Peut-être que ce n'est pas la meilleure option, peut-être pas la meilleure façon de le faire, mais cela ouvrira de l'espace pour créer des animations passionnantes et ravissantes pour inspirer d'autres personnes pour une meilleure solution.

Il vous permettra d'utiliser un style dégradé sur les textes, qui est même supporté par IE8!

Ici vous pouvez trouver une démo en direct et le référentiel d'origine est ici aussi sur GitHub, open source et prêt à recevoir des mises à jour (: D)

C'est ma première fois (ouais, après 5 ans, vous avez bien entendu) de mentionner ce référentiel n'importe où sur Internet, et j'en suis ravi!


[Mise à jour - août 2019:] Github a supprimé la démonstration des pages github de ce référentiel parce que je viens d'Iran! Seul le code source est disponible ici ...

mrReiha
la source