repeating-linear-gradient spacing becomes out-of-sync - html

I'm attempting to use repeating-linear-gradient to zebra-stripe a code block. To that end, I specified an explicit line-height in the code block and alternated the color at intervals of that value.
It works great for a few lines, but the text and stripes eventually stop lining up. Does anyone know why this is and whether it can be fixed?
pre {
font-family: monospace;
font-size: 12px;
line-height: 1.4em;
background: repeating-linear-gradient(
to bottom,
transparent 0,
transparent 1.4em,
#ddd 1.4em,
#ddd 2.8em);
}
<pre>Here
I
will
write
many
lines
of
text
and
the
spacing
starts
out
quite
well
but
eventually
the
lines
and
stripes
get
messed
up
and
this
makes
me
sad.</pre>

From w3.org:
On a block container element whose content is composed of inline-level
elements, 'line-height' specifies the minimal height of line boxes
within the element.
The keyword here being "minimal". If the font-size is large enough it will increase the spacing of your lines to more than your defined line-height.
To illustrate, here is your snippet with a smaller font-size:
pre {
font-family: monospace;
font-size: 10px;
line-height: 1.4em;
background: repeating-linear-gradient(
to bottom,
transparent 0,
transparent 1.4em,
#ddd 1.4em,
#ddd 2.8em);
}
<pre>Here
I
will
write
many
lines
of
text
and
the
spacing
starts
out
quite
well
and
the
lines
and
stripes
don't
ever
get
messed
up
and
this
makes
me
happy. :-)</pre>
Or here with a larger line-height:
pre {
font-family: monospace;
font-size: 12px;
line-height: 2em;
background: repeating-linear-gradient(
to bottom,
transparent 0,
transparent 2em,
#ddd 2em,
#ddd 4em);
}
<pre>Here
I
will
write
many
lines
of
text
and
the
spacing
starts
out
quite
well
and
the
lines
and
stripes
don't
ever
get
messed
up
and
this
makes
me
happy. :-)</pre>

Related

Reveal animated background for specified text spans on mouse hover

Goal
A hero section with text
The hero text contains spans
A circle follows the mouse position
Where the circle overlaps the spans, an animated background is revealed
All other text remains black, even if they are within the circle
Ideally, I'd like to use a single animated background that is shared across all spans
Mockup
I can't figure out how to set up the HTML and CSS for this.
What I have So Far
I got a part of it working, though it's in a round-about way and I'm not sure the approach will let me continue on toward the desired goal.
The solution uses a background image applied to the heading text with background-clip: text;. If I'm not mistaken, this approach won't let me achieve the circle-reveal effect. I assume for that the image needs to be a separate layer below the text so I can mask it with the circle that follows the mouse.
Instead of revealing the background for the selected spans, I'm revealing the background for the entire h1, and using spans to define which text should remain black. For some reason I couldn't get it to work the other way around.
<h1 class="text-animated-bg">
<span class="text-black">This is some</span> text <span class="text-black">that I wrote with</span> various words <span class="text-black">that reveal an animated </span>background
</h1>
.text-animated-bg {
padding-top: 20px;
padding-bottom: 20px;
background-image: url("animation.gif");
background-position: 0px 0px;
background-size: cover;
font-family: Ogg, sans-serif;
color: #000;
font-style: italic;
font-weight: 700;
text-align: center;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.text-black {
background-image: -webkit-gradient(linear, left top, left bottom, from(#000), to(#000));
background-image: linear-gradient(180deg, #000, #000);
font-family: Inconsolata, monospace;
font-style: normal;
font-weight: 400;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
Ask
Any ideas on how to approach the HTML and CSS to achieve the desired effect?

Validation (CSS 3.0) "text" is not a valid value for the "-webkit-background-clip" property

So this is my code:
font-size: 44px;
font-weight: 500;
background: linear-gradient(to-right, #494964, #6f6f89);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
I wanted to use the background clip property to clip the background to the text. Problem is visual studio is not recognizing the text property. What can I do to fix this?
You need to make sure you are setting the background-clip property on the parent text element i.e. <p> tag then you can apply the background color as a class. Please see below for a working example.
Please note your linear gradient declaration should also be written like below without the hyphen in to-right:
background: linear-gradient(to right, #494964, #6f6f89);
.container p {
background-clip: text;
-webkit-background-clip: text;
color: rgba(0, 0, 0, 0.2);
font: 900 1.2em sans-serif;
}
.background-color {
background: linear-gradient(60deg, blue, yellow, red, yellow, red);
}
<div class="container">
<p class="background-color">
The background is clipped to the foreground text.
</p>
</div>
This could also have to do with the fact that background-clip: text is an experimental feature, according to MDN docs

Different background colors for each line in the textarea (or editable div?)

I have a textarea for user text input and I want each line to have different background color (from a predefined set of 10 colors, can be repeated if more lines). I understand that I can use CSS expressions like nth-of-type(10n+1) for the tables, static text etc. - but not sure how to implement it for the textarea content.
(attached snippet doesn't really do anything about that, it's just a template to work with)
.my1 {
background-image:
repeating-linear-gradient(white, white 30px, gray 31px, white 31px);
line-height: 31px;
padding: 8px 10px;
}
<textarea class="my1"></textarea>
Simply define the 10 colors inside your gradient.
Example with 4 colors:
.my1 {
--l:1.5em; /* height of line */
background-image:
repeating-linear-gradient(
red 0 calc(var(--l)*1),
green calc(var(--l)*1) calc(var(--l)*2),
blue calc(var(--l)*2) calc(var(--l)*3),
purple calc(var(--l)*3) calc(var(--l)*4));
line-height: var(--l);
color:#fff;
}
<textarea class="my1"></textarea>
If you want padding, you have to offset the gradient to avoid missalignment. Only an offset from the top is required
.my1 {
--l:1.5em; /* height of line */
background:
repeating-linear-gradient(
red 0 calc(var(--l)*1),
green calc(var(--l)*1) calc(var(--l)*2),
blue calc(var(--l)*2) calc(var(--l)*3),
purple calc(var(--l)*3) calc(var(--l)*4)) 0 8px no-repeat,
yellow;
line-height: var(--l);
padding:8px 10px;
color:#fff;
}
<textarea class="my1"></textarea>

Pre element not respecting right padding

I have a pre element with the following styles:
pre {
background: #555;
background-image: -webkit-linear-gradient(#555 50%, #505050 50%);
background-image: -moz-linear-gradient(#555 50%, #505050 50%);
background-image: -ms-linear-gradient(#555 50%, #505050 50%);
background-image: -o-linear-gradient(#555 50%, #505050 50%);
background-image: linear-gradient(#555 50%, #505050 50%);
background-position: 0 0;
background-repeat: repeat;
background-size: 4.5em 4.5em;
color: #fff;
font-size: .8em;
line-height: 2.25;
margin: 0 -2.25em 2.25em;
overflow: auto;
padding: 2.25em;
}
Why, when scrolling the pre element, is the right padding being ignored? I don't want long lines to wrap, I want this behavior (it is not expected behaviour based on the specification, but seems to work in webkit): http://jsfiddle.net/joshnh/Ly5kz/
Here is a link to a live example: http://joshnh.com/2012/08/14/making-a-pure-css-featured-image-slider/#step1
That's not quite how padding works. If your content is being forced past the edge of the box it will continue on without being covered by the background. Padding is room around the inner section of the box. All text that fits in the box will have x amount of space between it and the box edge.
In order to have a padding-like matte/box/border you'll need to have a wrapper div that has the border and padding and add your other styles to the pre.
http://jsfiddle.net/ktJ3g/
pre elements are white-space:nowrap by default, you need to set some sort of wrap attribute. Here are your options: http://www.w3schools.com/cssref/pr_text_white-space.asp
Try white-space: pre-wrap; - Also, I think your kind of abusing the lang attribute by using it to identify the content as containing html or css. I believe it should be used to indicate the language encoding of the content, i.e. en_US, fr_FR, etc
A note for prism.js-based <pre> elements:
You can use the normalize-whitespace plugin:
import 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace';
https://prismjs.com/plugins/normalize-whitespace/
https://github.com/PrismJS/prism/tree/master/plugins

box around each letter with css without using spans

I'm trying to create a box around each letter to use for an odometer style stat counter. Do you know how to do this without wrapping each letter in a span? If you have any ideas I'd love to hear them.
If you are using a mono spaced font, you could probably use a background image with the boxes.
Another option would be to use javascript to add in all the extra markup you need. There are some jquery plugins that do this type of thing already:
http://daverupert.com/2010/09/lettering-js/
Using CSS3 gradients you can do this with pure css and no javascript. The main idea is to create a gradient where the box color you want is a solid color to a certain color stop, and then the gradient is transparent. You have to calculate the color stops in coordination with the font-size and letter-spacing of the text. Then apply the gradient to a pseudo class of the text's element and voila.
Here's an example I created for a span element that contained the amount of money raised for an organization. Each number needed a pink box around it. The reason the gradient is so complicated is because I made it only repeat after every 3 digits, since every 3 digits there was a comma that needed to be outside of the boxes and thus required an extra gap. If you are repeating after every character it can be much simpler, but figured I'd share this approach since you mentioned an odometer. You can also extend these gradients with more browser-prefixes to make it work in IE, opera, etc.
html:
<span id="amount-raised">10,123</span>
css:
span#amount-raised {
position: absolute;
z-index: 1;
font-size: 70px;
letter-spacing: 10px;
color: #fff;
}
span#amount-raised:before { /* pink boxes */
content: '';
position: absolute;
top: 0; left: 0;
z-index: -1;
height: 100%; width: 100%;
background-image: -webkit-repeating-linear-gradient(right, pink, pink 50px, transparent 50px, transparent 55px, pink 55px, pink 105px, transparent 105px, transparent 110px, pink 110px, pink 160px, transparent 160px, transparent 176px);
background-image: -moz-repeating-linear-gradient(right, pink, pink 50px, transparent 50px, transparent 55px, pink 55px, pink 105px, transparent 105px, transparent 110px, pink 110px, pink 160px, transparent 160px, transparent 176px);
}
I can't see a way to do this in HTML without wrapping each letter in an element that you can style.
You could create ten gifs, one for each number (you said stat counter) that look the way you want them. When you load the page, use javascript to split your string into an array, then loop through it and replace each character with the corresponding gif for that number.
Well, it's certainly possible to flip this around and use a font (via #font-face) that has boxed-in letters.
I liked DMTinter's answer but it was longer than necessary (plus it's 7 years old) - here's a quick and simple example css that I'm using on my page:
span { color: black;
font-family: "Lucida Console", Monaco, monospace;
border: 1px solid black;
background-image: repeating-linear-gradient(90deg, white, white 13.5px, black 14.5px);
}
The important thing is repeating-linear-gradient(). I just did trial and error to arrive at the values 13.5px and 14.5px as lining up with the background well.