Thursday 23 November 2017

javascript - Is it possible to apply CSS to half of a character?

itemprop="text">


What I am
looking for:



A way to style one
HALF of a character. (In this case, half the letter being
transparent)



What I have currently
searched for and tried (With no
luck):




  • Methods
    for styling half of a character/letter

  • Styling part of a
    character with CSS or JavaScript


  • Apply CSS to
    50% of a character



Below
is an example of what I am trying to
obtain.



src="https://i.stack.imgur.com/SaH8v.png"
alt="x">



Does a CSS or JavaScript solution
exist for this, or am I going to have to resort to images? I would prefer not to go the
image route as this text will end up being generated
dynamically.



/>


UPDATE:



Since
many have asked why I would ever want to style half of a character, this is why. My city
had recently spent $250,000 to define a new "brand" for itself. This href="https://web.archive.org/web/20140428135239/http://halifaxdefined.ca/img/halifax_logo_new.png"
rel="noreferrer">logo
is what they came up with. Many people
have complained about the simplicity and lack of creativity and continue to do so. My
goal was to come up with this href="http://gameovercancer.ca/tests/brandgenerator/"
rel="noreferrer">website
as a joke. Type in 'Halifax' and
you will see what I mean.


itemprop="text">
class="normal">Answer






src="https://i.stack.imgur.com/Glo2Q.png" alt="enter image description here"> Feel
free to fork and
improve.






/>


  • Pure
    CSS
    for a Single Character

  • JavaScript used
    for automation across text or multiple
    characters

  • Preserves Text Accessibility for screen
    readers for the blind or
    visually
    impaired






src="https://i.stack.imgur.com/ZYic1.png" alt="Half Style on
text">



Demo:
rel="noreferrer">http://jsfiddle.net/arbel/pd9yB/1694/



/>

This works on any dynamic text, or a single
character, and is all automated. All you need to do is add a class on the target text
and the rest is taken care of.




Also,
the accessibility of the original text is preserved for screen readers for the blind or
visually impaired.



Explanation for
a single character:



Pure CSS. All
you need to do is to apply .halfStyle class to each element
that contains the character you want to be
half-styled.



For each span element containing
the character, you can create a data attribute, for example here
data-content="X", and on the pseudo element use
content: attr(data-content); so the
.halfStyle:before class will be dynamic and you won't need to
hard code it for every
instance.



Explanation for any
text:




Simply add
textToHalfStyle class to the element containing the
text.






class="snippet" data-lang="js" data-hide="false" data-console="true"
data-babel="false">

class="snippet-code-js lang-js prettyprint-override">// 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('' + text +
'
');

// 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 +=
'';
}

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

            src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

Single
Characters:


data-content="X">X
data-content="Y">Y
data-content="Z">Z
data-content="A">A




Automated:



class="textToHalfStyle">Half-style,
please.





( href="http://jsfiddle.net/arbel/pd9yB/1695/" rel="noreferrer">JSFiddle
demo)




/>



src="https://i.stack.imgur.com/zYa0F.png" alt="Half Style on text - advanced - With Text
Shadow">



With this
solution you can style left and right parts, individually and
independently
.



Everything
is the same, only more advanced CSS does the
magic.




data-hide="true" data-console="true" data-babel="false">
class="snippet-code snippet-currently-hidden">
class="snippet-code-js lang-js prettyprint-override">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('' + text +
'
');

// 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 += '';
}

// Write to DOM only once

$el.append(output);

});
});

.halfStyle {
position:
relative;
display: inline-block;

font-size: 80px; /* or
any font size will work */
color: transparent; /* hide the base character
*/
overflow: hidden;
white-space: pre; /* to preserve the spaces
from collapsing */
}

.halfStyle:before { /* creates the
left part */
display: block;
z-index: 1;
position:
absolute;

top: 0;
width: 50%;
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
#af0; /* for demo purposes */
}

.halfStyle:after { /*
creates the right part */

display: block;
direction:
rtl; /* very important, will make the width to start from right */
position:
absolute;
z-index: 2;
top: 0;
left: 50%;

width: 50%;
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 #0af; /* for demo purposes
*/
}

            src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

Single
Characters:


data-content="X">X
data-content="Y">Y
data-content="Z">Z
data-content="A">A




Automated:



class="textToHalfStyle">Half-style,
please.





( href="http://jsfiddle.net/arbel/pd9yB/1695/" rel="noreferrer">JSFiddle
demo)




/>

/>



Now that we know what is
possible, let's create some variations.



/>


-Horizontal Half
Parts




  • Without
    Text Shadow:



    src="https://i.stack.imgur.com/i8dpE.png" alt="Horizontal Half Parts - No Text
    Shadow">


  • Possibility of Text
    Shadow for each half part
    independently:



    src="https://i.stack.imgur.com/2eDaQ.png" alt="halfStyle - Horizontal Half Parts - With
    Text
    Shadow">





class="snippet" data-lang="js" data-hide="true" data-console="true"
data-babel="false">

// 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('' + text +
'
');

// 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 += '';
}

// Write to DOM only once

$el.append(output);

});
});

.halfStyle {


position: relative;
display: inline-block;
font-size: 80px; /* or
any font size will work */
color: transparent; /* hide the base character
*/
overflow: hidden;
white-space: pre; /* to preserve the spaces
from collapsing */
}

.halfStyle:before { /* creates the
top part */
display: block;

z-index: 2;

position: absolute;
top: 0;
height: 50%;
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
#af0; /* for demo purposes
*/
}


.halfStyle:after { /* creates the bottom
part */
display: block;
position: absolute;
z-index:
1;
top: 0;
height: 100%;
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 #0af; /* for demo purposes
*/
}

            src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

Single
Characters:


data-content="X">X
data-content="Y">Y
data-content="Z">Z
data-content="A">A




Automated:



class="textToHalfStyle">Half-style,
please.





( href="http://jsfiddle.net/arbel/pd9yB/1696/" rel="noreferrer">JSFiddle
demo)




/>




-Vertical 1/3
Parts




  • Without
    Text Shadow:



    src="https://i.stack.imgur.com/paJvV.png" alt="halfStyle - Vertical 1/3 Parts - No Text
    Shadow">



  • Possibility of
    Text Shadow for each 1/3 part
    independently:



    src="https://i.stack.imgur.com/ypn4X.png" alt="halfStyle - Vertical 1/3 Parts - With
    Text Shadow">




class="snippet" data-lang="js" data-hide="true" data-console="true"
data-babel="false">

// 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('' + text +
'
');


// 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 += ' aria-hidden="true" class="halfStyle" data-content="' + chars[i] + '">' + chars[i] +
'';
}

// Write to DOM only
once

$el.append(output);

});
});

.halfStyle { /* base char and also the
right 1/3 */
position: relative;
display: inline-block;

font-size: 80px; /* or any font size will work */
color: transparent; /* hide
the base character */
overflow: hidden;
white-space: pre; /* to
preserve the spaces from collapsing */

color: #f0f; /* for demo
purposes */
text-shadow: 2px 2px 0px #0af; /* for demo purposes
*/
}

.halfStyle:before { /* creates the left 1/3
*/
display: block;
z-index: 2;
position:
absolute;
top: 0;
width: 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
#af0; /* for demo purposes */
}

.halfStyle:after { /*
creates the middle 1/3 */
display: block;
z-index:
1;

position: absolute;
top: 0;
width:
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
*/
}

            src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">


Single
Characters:


data-content="X">X
data-content="Y">Y
data-content="Z">Z
data-content="A">A



Automated:




class="textToHalfStyle">Half-style,
please.





( href="http://jsfiddle.net/arbel/pd9yB/1697/" rel="noreferrer">JSFiddle
demo)






/>


-Horizontal 1/3
Parts




  • Without
    Text Shadow:



    src="https://i.stack.imgur.com/M1unV.png" alt="halfStyle - Horizontal 1/3 Parts - No
    Text Shadow">


  • Possibility of Text
    Shadow for each 1/3 part independently:



    src="https://i.stack.imgur.com/UeuxW.png" alt="halfStyle - Horizontal 1/3 Parts - With
    Text
    Shadow">





class="snippet" data-lang="js" data-hide="true" data-console="true"
data-babel="false">

// 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('' + text +
'
');

// 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 += '';
}

// Write to DOM only once

$el.append(output);

});
});


class="snippet-code-css lang-css prettyprint-override">.halfStyle { /*
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: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: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 */
}

class="snippet-code-html lang-html prettyprint-override"> src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

Single
Characters:


data-content="X">X
data-content="Y">Y

data-content="Z">Z
data-content="A">A



Automated:



class="textToHalfStyle">Half-style,
please.






( href="http://jsfiddle.net/arbel/pd9yB/1698/" rel="noreferrer">JSFiddle
demo)






/>

-HalfStyle Improvement By
@KevinGranger



src="https://i.stack.imgur.com/PgdJ6.png" alt="halfStyle -
KevinGranger">




data-lang="js" data-hide="true" data-console="true"
data-babel="false">

// 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('' + text +
'
');

// 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 += '';
}

// Write to DOM only once

$el.append(output);

});
});

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;

}

class="snippet-code-html lang-html prettyprint-override"> src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

Single
Characters:


data-content="X">X
data-content="Y">Y
data-content="Z">Z
data-content="A">A



Automated:




class="textToHalfStyle">Half-style,
please.





( href="http://jsfiddle.net/arbel/pd9yB/1699/" rel="noreferrer">JSFiddle
demo)





/>


-PeelingStyle improvement of HalfStyle
by href="https://stackoverflow.com/users/3631752/sam-tremaine">@SamTremaine



src="https://i.stack.imgur.com/r67KC.png" alt="halfStyle -
SamTremaine">



data-hide="true" data-console="true" data-babel="false">
class="snippet-code snippet-currently-hidden">
class="snippet-code-js lang-js prettyprint-override">// 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('' + text +
'
');


// 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 += ' aria-hidden="true" class="halfStyle" data-content="' + chars[i] + '">' + chars[i] +
'';
}

// Write to DOM only
once

$el.append(output);

});
});

.halfStyle {
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: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;
}

            src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

Single
Characters:



data-content="X">X
data-content="Y">Y
data-content="Z">Z
data-content="A">A



Automated:



class="textToHalfStyle">Half-style,
please.






( href="http://jsfiddle.net/arbel/pd9yB/1700/" rel="noreferrer">JSFiddle demo
and on rel="noreferrer">samtremaine.co.uk)



/>
/>




Customized
different Half-Style style-sets can be used on desired elements on the same
page.
You can define multiple style-sets and tell the plugin which one to
use.



The plugin uses data attribute
data-halfstyle="[-CustomClassName-]" on the target
.textToHalfStyle elements and makes all the necessary changes
automatically.



So, simply on the element
containing the text add textToHalfStyle class and data
attribute data-halfstyle="[-CustomClassName-]". The plugin will
do the rest of the job.



src="https://i.stack.imgur.com/RxjKF.png" alt="halfStyle - Multiple on Same
Page">



Also the CSS style-sets' class
definitions match the [-CustomClassName-] part mentioned above
and is chained to .halfStyle, so we will have
.halfStyle.[-CustomClassName-]




class="snippet" data-lang="js" data-hide="false" data-console="true"
data-babel="false">

class="snippet-code-js lang-js prettyprint-override">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('' + halfstyle_text +
'
');

// 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 += ' aria-hidden="true" class="halfStyle ' + halfstyle_style + '" data-content="' +
halfstyle_chars[halfstyle_i] + '">' + halfstyle_chars[halfstyle_i] +
'';
}

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


class="snippet-code-html lang-html prettyprint-override"> src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">



Half-style,
please.



class="textToHalfStyle" data-halfstyle="hs-horizontal-third">Half-style,
please.



class="textToHalfStyle" data-halfstyle="hs-PeelingStyle">Half-style,
please.



style="background-color:#000;">
data-halfstyle="hs-KevinGranger">Half-style,
please.






( href="http://jsfiddle.net/arbel/pd9yB/1701/" rel="noreferrer">JSFiddle
demo)


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...