É possível aplicar CSS à metade de um caractere?

2817

O que estou procurando:

Uma maneira de estilizar um MEIO de um personagem. (Nesse caso, metade da letra é transparente)

O que eu procurei e tentei no momento (sem sorte):

  • Métodos para estilizar metade de um caractere / letra
  • Como estilizar parte de um personagem com CSS ou JavaScript
  • Aplicar CSS a 50% de um caractere

Abaixo está um exemplo do que estou tentando obter.

x

Existe uma solução CSS ou JavaScript para isso ou vou precisar recorrer a imagens? Eu preferiria não seguir a rota da imagem, pois esse texto acabará sendo gerado dinamicamente.


ATUALIZAR:

Como muitos perguntaram por que eu gostaria de criar metade de um personagem, é por isso. Minha cidade gastou recentemente US $ 250.000 para definir uma nova "marca" para si mesma. Este logotipo é o que eles criaram. Muitas pessoas se queixaram da simplicidade e falta de criatividade e continuam a fazê-lo. Meu objetivo era criar este site como uma piada. Digite 'Halifax' e você verá o que quero dizer.

Mathew MacLean
fonte
1
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Yvette
6
Eles estavam perguntando "por que" porque queriam saber por que você usaria CSS e não SVG ou um editor de imagens. Nada a ver com as decisões de negócios sobre seu logotipo. De acordo com o link para o logotipo deles, por que você não cortou o X?
user9993
1
Não posso reclamar deste logotipo. Muito melhor do que aquele maldito farol.
Parapluie
@Parapluie Eu tenho que concordar!
Mathew MacLean

Respostas:

2940

Agora no GitHub como um plug-in!

insira a descrição da imagem aqui Sinta-se livre para garfo e melhorar.

Demonstração | Faça o download do Zip | Half-Style.com (redireciona para o GitHub)


  • CSS puro para um único caractere
  • JavaScript usado para automação em texto ou vários caracteres
  • Preserva a acessibilidade de texto para leitores de tela para cegos ou deficientes visuais

Parte 1: Solução básica

Meio estilo no texto

Demo: http://jsfiddle.net/arbel/pd9yB/1694/


Isso funciona em qualquer texto dinâmico ou em um único caractere e é tudo automatizado. Tudo o que você precisa fazer é adicionar uma classe ao texto de destino e o restante será resolvido.

Além disso, a acessibilidade do texto original é preservada para os leitores de tela para cegos ou deficientes visuais.

Explicação para um único caractere:

CSS puro. Tudo o que você precisa fazer é aplicar a .halfStyleclasse a cada elemento que contém o caractere que você deseja que seja estilizado pela metade.

Para cada elemento de amplitude que contém o caractere, você pode criar um atributo de dados, por exemplo data-content="X", aqui , e no pseudo-elemento, content: attr(data-content);para que a .halfStyle:beforeclasse seja dinâmica e você não precisará codificá-la para todas as instâncias.

Explicação para qualquer texto:

Simplesmente adicione textToHalfStyleclasse ao elemento que contém o texto.


// 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>

( Demo do JSFiddle )


Parte 2: Solução avançada - partes esquerda e direita independentes

Meio estilo no texto - avançado - com sombra de texto

Com esta solução, você pode modelar as peças esquerda e direita, individual e independentemente .

Tudo é o mesmo, apenas CSS mais avançado faz a mágica.

( Demo do JSFiddle )



Parte 3: Combine e melhore

Agora que sabemos o que é possível, vamos criar algumas variações.


-Meias Partes Horizontais

  • Sem sombra de texto:

    Metade horizontal - Sem sombra de texto

  • Possibilidade de sombra de texto para cada metade da parte independentemente:

    halfStyle - Metades horizontais - Com sombra de texto

( Demo do JSFiddle )



-Vertical 1/3 Peças

  • Sem sombra de texto:

    halfStyle - Vertical 1/3 Partes - Sem sombra de texto

  • Possibilidade de sombra de texto para cada parte de 1/3 independentemente:

    halfStyle - Vertical 1/3 Partes - com sombra de texto

( Demo do JSFiddle )



-Horizontal 1/3 Peças

  • Sem sombra de texto:

    halfStyle - Horizontal 1/3 Partes - Sem sombra de texto

  • Possibilidade de sombra de texto para cada parte de 1/3 independentemente:

    halfStyle - Horizontal 1/3 Partes - com sombra de texto

( Demo do JSFiddle )



-HalfStyle Improvement Por @KevinGranger

halfStyle - KevinGranger

( Demo do JSFiddle )



-PeelingStyle melhoria do HalfStyle por @SamTremaine

halfStyle - SamTremaine

( Demo do JSFiddle e em samtremaine.co.uk )



Parte 4: Pronto para produção

Diferentes conjuntos de estilos de meio estilo personalizados podem ser usados ​​nos elementos desejados na mesma página. Você pode definir vários conjuntos de estilos e dizer ao plugin qual usar.

O plug-in usa o atributo de dados data-halfstyle="[-CustomClassName-]"nos .textToHalfStyleelementos de destino e faz todas as alterações necessárias automaticamente.

Portanto, simplesmente no elemento que contém o texto, adicione textToHalfStyleclasse e atributo de dados data-halfstyle="[-CustomClassName-]". O plug-in fará o resto do trabalho.

halfStyle - Várias na mesma página

As definições de classe dos conjuntos de estilos CSS também correspondem à [-CustomClassName-]parte mencionada acima e estão encadeadas .halfStyle, portanto, teremos.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>

( Demo do JSFiddle )

Arbel
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Yvette
7
Isso é muito legal. Vale ressaltar que essa técnica quebra CSS de quebra de linha, espaço em branco e espaçamento entre caracteres.
Andrew Ensley
2
É bom ver que voltamos ao WordArt: D
rovyko
488

insira a descrição da imagem aqui


Acabei de desenvolver o plugin e está disponível para uso de todos! Espero que você goste.

Exibir projeto no GitHub - Exibir site do projeto . (para que você possa ver todos os estilos divididos)

Uso

Primeiro de tudo, verifique se a jQuerybiblioteca está incluída. A melhor maneira de obter a versão mais recente do jQuery é atualizar sua tag de cabeça com:

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

Após o download dos arquivos, inclua-os no seu projeto:

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

Marcação

Tudo o que você precisa fazer é atribuir a classe splitchar, seguida pelo estilo desejado ao elemento que envolve o texto. por exemplo

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

Depois de tudo isso, certifique-se de chamar a função jQuery no arquivo pronto para seu documento, como este:

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

Customizando

Para que o texto fique exatamente como você deseja, basta aplicar o design da seguinte forma:

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


É isso aí! Agora você tem o Splitcharplugin pronto. Mais informações sobre o assunto em http://razvanbalosin.com/Splitchar.js/ .

Razvan B.
fonte
A partir de agora, sua solução é a mais fácil de implementar para vários caracteres, mas ainda não está 100% lá.
Mathew MacLean
@MathewMacLean emisfera tem que ter a resposta, certo?
Mttdbrd 9/05
3
Isso tem problemas com a quebra de texto exibida mesmo no violino mais recente. Quando um personagem termina, ele basicamente se divide em dois. Deve ser uma correção trivial, no entanto.
BoltClock
16
Não dependa do jquery-latest.min.js, ele poderá quebrar seus sites sem aviso se o jQuery for atualizado e o plug-in não funcionar com o mais novo. Em vez disso: use uma versão específica e verifique a compatibilidade ao atualizar.
Niels Bom
2
Você pode editar sua resposta para não sugerir o uso de jquery-latest.js. Como o @NielsBom mencionou, no passado, ele poderia interromper o site quando fosse atualizado. Desde julho de 2014, isso não acontece, mas é porque está bloqueado na versão 1.11.1 e nunca será atualizado novamente.
Código inútil
237

Editar (outubro de 2017): background-clipou melhor, background-image optionsagora são suportados por todos os principais navegadores: CanIUse

Sim, você pode fazer isso com apenas um caractere e apenas CSS.

Apenas Webkit (e Chrome), no entanto:

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>

Visualmente, todos os exemplos que usam dois caracteres (seja JS, pseudo elementos CSS ou apenas HTML) parecem bons, mas observe que todos adicionam conteúdo ao DOM que pode causar acessibilidade - assim como seleção / corte de texto / colar problemas.

DA.
fonte
34
@ MathewMacLean, nossos trabalhos seriam muito mais fáceis se o IE morresse e o Firefox começasse a usar o Webkit. :)
DA.
48
O WebKit tem um histórico de renderização de bugs que são quase bizarros no nível IE6 / IE7 (você pode até dizer que o Safari e o Chrome são o IE6 da web moderna) e se comportando de maneiras que se desviam do padrão sem motivo específico. O IE está muito melhor desde a versão 9, portanto, enquanto as versões antigas já deveriam morrer, não vejo razão para o ódio por suas versões recentes. E certamente não vejo por que as pessoas apóiam a ideia de uma monocultura WebKit / Blink (os comentários aqui provavelmente são de brincadeira, mas ouvi falar de pessoas que acreditam seriamente nisso).
BoltClock
3
Dito isto, background-clip: texté super incrível e eles devem considerá-lo (ou algo semelhante text-decoration-background) para um módulo de nível 4.
BoltClock
2
Sim, eu ficaria mais feliz se o blink / webkit morresse e os modernos mecanismos de renderização do IE + FF sobrevivessem do que o contrário. O que não quer dizer que o resto do chrome não seja bom, apenas que sua renderização é praticamente a pior do grupo atualmente.
Eamon Nerbonne
2
Esta é uma solução muito mais limpa do que as bibliotecas hacky acima, deve ser uma resposta aceita, pois os gradientes de texto são utilizáveis ​​atualmente.
mystrdat
160

Exemplo


JSFiddle DEMO

Vamos fazê-lo usando apenas pseudo-seletores CSS!

Essa técnica funcionará com conteúdo gerado dinamicamente e diferentes tamanhos e larguras de fonte.

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;
}

Para quebrar a cadeia gerada dinamicamente, você pode usar uma função como esta:

// 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
fonte
Isso é legal, mas o único problema é que o conteúdo será dinâmico.
Mathew MacLean
Os resultados variam dependendo da fonte usada. Além disso, calcular a largura parece um problema.
j08691
@MathewMacLean hmm, seu conteúdo seria apenas um personagem? Caso contrário, você gostaria que cada personagem tivesse o mesmo efeito de cor dividida ou apenas alguns (por exemplo, o primeiro)?
Wvandaal
1
@ MathewMacLean, você pode escrever uma função de loop simples em JS para realizar o empacotamento. Estou adicionando à minha resposta agora.
Wvandaal
1
@MathewMacLean De onde vem o texto? wvandaal está certo, você pode embrulhar o texto você mesmo.
Mttdbrd 9/05
96

Pode ser irrelevante, talvez não, mas há algum tempo atrás eu criei uma função jQuery que faz a mesma coisa, mas horizontalmente.

Eu chamei de "Strippex" Para 'stripe' + 'text', demo: http://cdpn.io/FcIBg

Não estou dizendo que essa é a solução de qualquer problema, mas já tentei aplicar css à metade de um personagem, mas horizontalmente. Portanto, a ideia é a mesma, a realização pode ser horrível, mas funciona.

Ah, e o mais importante, eu me diverti criando!

insira a descrição da imagem aqui

LukyVj
fonte
2
@Luky Vj: Essa conta é sua? Convém consolidar todas as suas postagens em uma única conta para não encontrar obstáculos ao tentar editar suas próprias postagens.
BoltClock
Sim, na verdade, eu postei primeiramente com minha primeira conta antiga .. E eu tive que adicionar uma imagem e não era popular o suficiente para postar minha imagem .. Mas você está certo, eu vou consertar o mais rápido possível !
LukyVj
1
@LukyVj: Você pode mesclar suas contas seguindo as instruções aqui: stackoverflow.com/help/merging-accounts
BoltClock
1
@LukyVj Atualizei sua função adicionando pointer-events:nonea &:nth-child(2)- &:nth-child(5). Isso faz com que o texto possa ser destacado apenas uma vez e você receberá apenas uma cópia. Você pode vê-lo aqui: codepen.io/anon/pen/upLaj
Mathew MacLean
74

Se você está interessado nisso, o Glitch de Lucas Bebber é um efeito muito semelhante e super legal:

insira a descrição da imagem aqui

Criado usando um SASS Mixin simples, como

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

Mais detalhes nas CSS Tricks de Chris Coyer e na página Codepen de Lucas Bebber

Ruskin
fonte
74

Aqui está uma implementação feia na tela. Eu tentei esta solução, mas os resultados são piores do que eu esperava, então aqui está mesmo assim.

Exemplo de tela

$("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
fonte
1
Aliás, você também pode usar 0.5a parada de cor vermelha.
Escova de dentes
62

O mais próximo que posso obter:

$(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>

Demo: http://jsfiddle.net/9wxfY/2/

Heres uma versão que usa apenas uma extensão: http://jsfiddle.net/9wxfY/4/

Prisioneiro
fonte
1
$('span').width()apenas retorna a largura do primeiro vão encontrado; teria que ser algo que você fez para cada par. O que me dá uma idéia ...
Pointy
Isso é bastante semelhante ao exemplo de epascarello, encontrado em jsfiddle.net/9WWsd. Como eu disse a ele, seu exemplo é um passo na direção certa, mas seria um pesadelo usar em uma escala maior.
Mathew MacLean
@MathewMacLean, eu não vi isso. Por que seria um pesadelo? Que tal isso: jsfiddle.net/9wxfY/4
Prisioneiro
Quando você implementa mais de um caractere, isso causa problemas.
Mathew MacLean
@MathewMacLean que é onde o fabulosas Lettering.JS entra.
Pointy
53

Digite a descrição da imagem aqui

Acabei de jogar com a solução da @ 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
fonte
4
Acabei de jogar com a solução @Arbel Quais são as diferenças com a solução da Arbel? É difícil ver se você apenas copiou ou colou algum código ou o melhorou.
AL
43

Outra solução apenas para CSS (embora o atributo de dados seja necessário se você não quiser escrever CSS específico para uma letra). Este funciona mais amplamente (Testado IE 9/10, Chrome mais recente e FF mais recente)

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
fonte
38

Solução CSS e jQuery limitada

Não tenho certeza de quão elegante é essa solução, mas corta tudo exatamente ao meio: http://jsfiddle.net/9wxfY/11/

Caso contrário, criei uma boa solução para você ... Tudo o que você precisa fazer é ter isso no seu HTML:

Dê uma olhada nesta edição mais recente e precisa a partir de 13/06/2016: http://jsfiddle.net/9wxfY/43/

Quanto ao CSS, é muito limitado ... Você só precisa aplicá-lo ao :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>

Adjit
fonte
Isso tem os mesmos problemas que os outros têm. Isso começa a ficar confuso quando você tenta fazer isso com mais de um personagem.
Mathew MacLean
@MathewMacLean Sei :( serra que também trabalhando nisso agora.
Adjit
O @MathewMacLean o corrigiu, mas não tem certeza de como o JQuery está limpo agora. Dê uma olhada
Adjit
@MathewMacLean adicionando à versão do webkit de coisas que você poderia usar uma solução como esta: jsfiddle.net/wLkVt/1
Adjunte
@MathewMacLean Corrigido o erro no meu script. O motivo do erro foi que eu estava usando a largura do primeiro elemento o tempo todo, em vez da largura das letras.
Adjit
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/

Você pode usar esse código para fazer todo tipo de coisa interessante - essa é apenas uma implementação que meu associado e eu vimos na noite passada.

Sam Tremaine
fonte
27

Uma boa solução exclusiva para o WebKit que aproveita o background-clip: textsuporte: 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
fonte
24

Que tal algo assim para textos mais curtos?

Pode até funcionar para textos mais longos se você fizer algo com um loop, repetindo os caracteres com JavaScript. De qualquer forma, o resultado é algo como isto:

É possível aplicar CSS à metade de um caractere?

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
fonte
23

FWIW, aqui está minha opinião sobre isso, apenas com CSS: http://codepen.io/ricardozea/pen/uFbts/

Várias notas:

  • A principal razão pela qual fiz isso foi me testar e ver se consegui estilizar metade de um personagem e, ao mesmo tempo, fornecer uma resposta significativa ao OP.

  • Estou ciente de que essa não é uma solução ideal ou a mais escalável, e as soluções propostas pelas pessoas aqui são muito melhores para cenários do "mundo real".

  • O código CSS que criei é baseado nos primeiros pensamentos que vieram à minha mente e em minha própria abordagem pessoal ao problema.

  • Minha solução funciona apenas em caracteres simétricos, como X, A, O, M. ** Não funciona em caracteres assimétricos como B, C, F, K ou letras minúsculas.

  • ** Entretanto, essa abordagem cria 'formas' muito interessantes com caracteres assimétricos. Tente alterar o X para um K ou para uma letra minúscula como um h ou p no 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
fonte
17

Você também pode fazê-lo usando SVG, se desejar:

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
fonte
16

Isso pode ser conseguido apenas com o :beforeseletor CSS e 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>

>> Veja no jsFiddle

Sleek Geek
fonte
8

Você pode usar o código abaixo. Aqui, neste exemplo, usei h1tag e adicionei um atributo data-title-text="Display Text"que aparecerá com texto em cores diferentes no h1elemento de texto tag, o que dá um efeito de texto em meia-cor conforme mostrado no exemplo abaixo

insira a descrição da imagem aqui

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
fonte
5

Apenas para o registro na história!

Eu vim com uma solução para meu próprio trabalho de 5 a 6 anos atrás, que é Gradext (javascript puro e css puro, sem dependência).

A explicação técnica é que você pode criar um elemento como este:

<span>A</span>

agora, se você quiser fazer um gradiente no texto, precisará criar várias camadas, cada uma individualmente colorida e o espectro criado ilustrará o efeito de gradiente.

por exemplo, observe esta é a palavra lorem dentro de a <span>e causará um efeito de gradiente horizontal ( verifique os exemplos ):

 <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>

e você pode continuar fazendo esse padrão por um longo período de tempo e também por um longo parágrafo.

insira a descrição da imagem aqui

Mas!

E se você quiser criar um efeito de gradiente vertical nos textos?

Depois, há outra solução que pode ser útil. Vou descrever em detalhes.

Assumindo o nosso primeiro <span>novamente. mas o conteúdo não deve ser as letras individualmente; o conteúdo deve ser o texto inteiro, e agora vamos copiar o mesmo <span>uma e outra vez Veja isso:

<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>

insira a descrição da imagem aqui

Mais uma vez, mas!

e se você quiser criar esses efeitos de gradiente para mover e criar uma animação a partir dele?

bem, há outra solução para isso também. Você definitivamente deve verificar animation: trueou mesmo o .hoverable()método que levará a um gradiente para começar com base na posição do cursor! (soa legal xD)

insira a descrição da imagem aqui

é assim que estamos criando gradientes (lineares ou radiais) nos textos. Se você gostou da idéia ou deseja saber mais sobre ela, verifique os links fornecidos.


Talvez essa não seja a melhor opção, talvez não seja a melhor maneira de fazer isso, mas abrirá algum espaço para criar animações emocionantes e deliciosas para inspirar outras pessoas a encontrar uma solução melhor.

Isso permitirá que você use o estilo gradiente nos textos, o que é suportado pelo IE8!

Aqui você pode encontrar uma demonstração ao vivo em funcionamento e o repositório original também está no GitHub, de código aberto e pronto para receber algumas atualizações (: D)

Esta é a minha primeira vez (sim, depois de cinco anos, você ouviu direito) mencionar este repositório em qualquer lugar da Internet, e estou empolgado com isso!


[Atualização - agosto de 2019:] O Github removeu a demonstração de páginas do github desse repositório porque eu sou do Irã! Somente o código fonte está disponível aqui ...

mrReiha
fonte