Last active
June 4, 2020 21:19
-
-
Save MrBlank/604e2575775345f01de8c82408529541 to your computer and use it in GitHub Desktop.
Arcade Pixel Font - CRT Scanlines!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Inspired by Arcade Game Typography | |
* https://www.itsnicethat.com/articles/toshi-omagari-arcade-game-typography-publication-graphic-design-231019 | |
*/ | |
/* scanlines - Creates a repeating-linear-gradient over text | |
* | |
* @param $font-size (Required) in px | |
* @param $line-height (Required) in px | |
* @param $colors (Required) at least one color, each color makes a scanline | |
*/ | |
@mixin scanlines($font-size, $line-height, $colors...) { | |
display: inline-block; | |
font-size: $font-size; | |
line-height: $line-height; | |
// Check and see if browser supports text-fill-color | |
@supports (-webkit-text-fill-color: transparent) { | |
$colors-count: length($colors); | |
$scanline-above: ($line-height - $font-size) / 2; // Where top of letters start. The line height above | |
$scanline-height: $font-size / $colors-count; // height of each scanline | |
// Build the scanline gradient | |
$stops: (); | |
@for $i from 1 through $colors-count { | |
$color: nth($colors, $i); | |
$new-stops: (); | |
@if $i == 1 { // First line | |
$new-stops: $color 0px, | |
$color ($scanline-above + $scanline-height); | |
} @else if $i == $colors-count { // Last line | |
$new-stops: $color ($scanline-above + $scanline-height * ($i - 1)), | |
$color $line-height; | |
} @else { // All others | |
$new-stops: $color ($scanline-above + $scanline-height * ($i - 1)), | |
$color ($scanline-above + $scanline-height * $i); | |
} | |
$stops: join($stops, $new-stops, comma); | |
} | |
background: repeating-linear-gradient(($stops)); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
} | |
} | |
/* scanlines-crt - Creates a repeating-linear-gradient with transparent gaps between each line (like a CRT display!) over text | |
* | |
* @param $font-size (Required) in px | |
* @param $line-height (Required) in px | |
* @param $gap (Required) a number for a percent | |
* @param $colors (Required) at least one color, each color makes a scanline | |
*/ | |
@mixin scanlines-crt($font-size, $line-height, $gap, $colors...) { | |
// May need to adjust font-size or line-height by a pixel to help scanlines align | |
display: inline-block; | |
font-size: $font-size; | |
line-height: $line-height; | |
// Check and see if browser supports text-fill-color | |
@supports (-webkit-text-fill-color: transparent) { | |
$colors-count: length($colors); | |
$scanline-above: ($line-height - $font-size) / 2; // Where top of letters start. The line height above | |
$scanline-height: $font-size / $colors-count; // height of each scanline | |
$scanline: $scanline-height * (1 - $gap); // height of color | |
$scanline-gap: $scanline-height * $gap; // height of gap | |
// Build the scanline gradient | |
$stops: (); | |
@for $i from 1 through $colors-count { | |
$color: nth($colors, $i); | |
$new-stops: (); | |
@if $i == 1 { // First Line | |
$new-stops: $color 0px, | |
$color ($scanline-above + $scanline-height - $scanline-gap), | |
transparent ($scanline-above + $scanline-height - $scanline-gap), | |
transparent ($scanline-above + $scanline-height); | |
} @else if $i == $colors-count { // Last line | |
$new-stops: $color ($scanline-above + $scanline-height * ($i - 1)), | |
$color ($scanline-above + $scanline-height * $i) - $scanline-gap, | |
transparent ($scanline-above + $scanline-height * $i) - $scanline-gap, | |
transparent $line-height; | |
} @else { // All in between | |
$new-stops: $color ($scanline-above + $scanline-height * ($i - 1)), | |
$color ($scanline-above + $scanline-height * $i) - $scanline-gap, | |
transparent ($scanline-above + $scanline-height * $i) - $scanline-gap, | |
transparent ($scanline-above + $scanline-height * $i); | |
} | |
$stops: join($stops, $new-stops, comma); | |
} | |
background: repeating-linear-gradient(($stops)); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
} | |
} | |
/* scanlines-shadow - Creates a text-shadow behind the scanline text with a before pseudo-element | |
* | |
* @HTML data-text (Required) attribute on the element with a copy of the scanline text | |
* @param $font-size (Required) in px | |
* @param $line-height (Required) in px | |
* @param $color (Required) color for the shadow | |
* @param $distance-x (Optional) in px to offset the x-axis, defaults to 10px | |
* @param $distance-y (Optional) in px to offset the y-axis, defaults to 7px | |
* @param $blur (Optional) in px for the blur-radius of the shadow, defaults to 0 | |
*/ | |
@mixin scanlines-shadow($font-size, $line-height, $color, $distance-x: 10px, $distance-y: 7px, $blur: 0) { | |
// Drop shadow | |
position: relative; | |
&:before { | |
content: attr(data-text); | |
position: absolute; | |
top: 0; | |
left: 0; | |
z-index: -1; | |
text-shadow: $distance-x $distance-y $blur $color; | |
} | |
} | |
/* scanlines-outline - Creates an outline on the text behind the scanline text with an after pseudo-element | |
* | |
* @HTML data-text (Required) attribute on the element with a copy of the scanline text | |
* @param $font-size (Required) in px | |
* @param $line-height (Required) in px | |
* @param $color (Required) color for the shadow | |
* @param $thickness (Optional) in px for the line thickness, defaults to 10px | |
* @param $distance-x (Optional) in px to offset the x-axis, defaults to 0 | |
* @param $distance-y (Optional) in px to offset the y-axis, defaults to 0 | |
*/ | |
@mixin scanlines-outline($font-size, $line-height, $color, $thickness: 10px, $distance-x: 0, $distance-y: 0) { | |
// Outline | |
position: relative; | |
&:after { | |
content: attr(data-text); | |
position: absolute; | |
top: 0; | |
left: 0; | |
z-index: -1; | |
transform: translate($distance-x, $distance-y); | |
-webkit-text-fill-color: $color; | |
-webkit-text-stroke: $thickness $color; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="container"> | |
<h1 class="scanlines-head" data-text="Arcade Game Typography"> | |
Arcade Game Typography | |
</h1> | |
<p class="scanlines-subhead" data-text="The Art of Pixel Type"> | |
The Art of Pixel Type | |
</p> | |
<div class="book"> | |
<a target="_blank" href="https://www.itsnicethat.com/articles/toshi-omagari-arcade-game-typography-publication-graphic-design-231019">Inspired by the book by Toshi Omagari</a> | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Scanline styles applied | |
// Play with the arguments to see various options. Check the mixin docs above to see what args are available. | |
// Font size and line height may need adjusting by a pixel or two for scanlines to perfectly align at different sizes. | |
// A pixel font - 8 scanlines works well with this font | |
@import url("https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap"); | |
.scanlines-head { | |
$scanlines-head-colors: #bf34ff, #bf34ff, #bf34ff, #ff00d0, #ff8500, #d0ff00, #50ff00, #50ff00; | |
$scanlines-head-shadow: darken(#af00ff, 60%); | |
$scanlines-gap: .35; | |
font-weight: 400; // Weight matters for scanline alignment and browser consistancy! | |
@include scanlines-crt(100px, 119px, $scanlines-gap, $scanlines-head-colors...); | |
@include scanlines-shadow(100px, 119px, $scanlines-head-shadow, 10px, 7px); | |
@media (max-width: 1300px) { | |
@include scanlines-crt(64px, 72px, $scanlines-gap, $scanlines-head-colors...); | |
@include scanlines-shadow(64px, 72px, $scanlines-head-shadow, 8px, 5px); | |
} | |
@media (max-width: 1000px) { | |
@include scanlines-crt(48px, 60px, $scanlines-gap, $scanlines-head-colors...); | |
@include scanlines-shadow(48px, 60px, $scanlines-head-shadow, 7px, 4px); | |
} | |
@media (max-width: 700px) { | |
@include scanlines-crt(32px, 48px, $scanlines-gap, $scanlines-head-colors...); | |
@include scanlines-shadow(32px, 48px, $scanlines-head-shadow, 6px, 4px); | |
} | |
@media (max-width: 400px) { | |
@include scanlines-crt(28px, 32px, $scanlines-gap, $scanlines-head-colors...); | |
@include scanlines-shadow(28px, 32px, $scanlines-head-shadow, 5px, 4px); | |
} | |
} | |
.scanlines-subhead { | |
$color-base: #d0ff00; | |
$scanlines-subhead-colors: | |
adjust-hue($color-base, -20deg), | |
adjust-hue($color-base, 0deg), | |
adjust-hue($color-base, 0deg), | |
adjust-hue($color-base, -20deg), | |
adjust-hue($color-base, -20deg), | |
adjust-hue($color-base, -30deg), | |
adjust-hue($color-base, -30deg), | |
adjust-hue($color-base, -35deg); | |
$scanlines-subhead-shadow: darken(#af00ff, 60%); | |
font-weight: 400; // Weight matters for scanline alignment and browser consistancy! | |
text-transform: uppercase; | |
@include scanlines(32px, 48px, $scanlines-subhead-colors...); | |
@include scanlines-outline(32px, 48px, $scanlines-subhead-shadow, 8px); | |
@media (max-width: 1300px) { | |
@include scanlines(20px, 24px, $scanlines-subhead-colors...); | |
@include scanlines-outline(20px, 24px, $scanlines-subhead-shadow, 6px); | |
} | |
@media (max-width: 1000px) { | |
@include scanlines(16px, 18px, $scanlines-subhead-colors...); | |
@include scanlines-outline(16px, 18px, $scanlines-subhead-shadow, 6px); | |
} | |
@media (max-width: 700px) { | |
@include scanlines(14px, 16px, $scanlines-subhead-colors...); | |
@include scanlines-outline(14px, 16px, $scanlines-subhead-shadow, 5px); | |
} | |
} | |
// Layout CSS | |
body { | |
font-family: "Press Start 2P", sans-serif; | |
color: rgba(255, 255, 255, .6); | |
background-color: #371d3a; | |
padding: 0; | |
margin: 0; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
height: 100vh; | |
} | |
.container { | |
padding: 40px; | |
@media (max-width: 700px) { | |
padding: 10px; | |
} | |
text-align: center; | |
h1, | |
p { | |
margin: 0 0 .4em 0; | |
} | |
.book { | |
a { | |
display: inline-block; | |
font-size: 12px; | |
background-color: rgba(255, 255, 255, .1); | |
color: rgba(255, 255, 255, .6); | |
text-decoration: none; | |
margin-top: 4em; | |
padding: .75em 1.5em .6em; | |
line-height: 1.3; | |
border-radius: 2em; | |
&:hover { | |
background-color: rgba(255, 255, 255, .2); | |
color: rgba(255, 255, 255, .9); | |
} | |
@media (max-width: 700px) { | |
font-size: 9px; | |
letter-spacing: 1px; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment