Mohammed Wahed Khan
Mohammed Wahed Khan

Reputation: 898

styling a <pre> tag

In my website documentation, I have some code that should be displayed like to suggest the user how they can change the look and feel of the website by following the displayed code. I don't want to use the background image inside this pre tag but want some styling for it. like every line of code should have an alternate background color. I've linked the inspiration image.

demo image

  pre {
  font-size: 20px;
  border: 2px solid grey;
  width: 450px;
  border-left: 12px solid green;
  border-radius: 5px;
  padding: 14px;
}
<pre>
.header-inner {
width: 1200px;
margin: 0 auto;
text-align: center;
font-size: 24px;
font-family: 'lato', sans-serif;
}
</pre>

Upvotes: 7

Views: 27201

Answers (3)

Hash
Hash

Reputation: 8050

As mentioned by other you can use linear gradiant

pre {
  font-size: 20px;
  border: 2px solid grey;
  width: 450px;
  border-left: 12px solid green;
  border-radius: 5px;
  padding: 14px;
  background-color: #2f2f2f;
  background-image: -webkit-repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  background-image: -moz-repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  background-image: -ms-repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  background-image: -o-repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  background-image: repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  padding: 0em 1em;
  white-space: pre-wrap;
  word-wrap: break-word;
}
<pre>
.header-inner {
width: 1200px;
margin: 0 auto;
text-align: center;
font-size: 24px;
font-family: 'lato', sans-serif;
}
</pre>

Simple approach,

$("pre").html(function (index, html) {
    return html.replace(/^(.*)$/mg, "<span class=\"line\">$1</span>")
});
pre {
  counter-reset: line-numbering;
  background: #2c3e50;
  padding: 12px 0px 14px 0;
  width: 600px;
  color: #ecf0f1;
  line-height: 100%;
}

pre .line::before {
  content: counter(line-numbering);
  counter-increment: line-numbering;
  padding-right: 1em;
  /* space after numbers */
  padding-left: 8px;
  width: 1.5em;
  text-align: right;
  opacity: 0.5;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre>
.header-inner {
width: 1200px;
margin: 0 auto;
text-align: center;
font-size: 24px;
font-family: 'lato', sans-serif;
}
</pre>

With line numbers,

$("pre").html(function(index, html) {
  return html.replace(/^(.*)$/mg, "<span class=\"line\">$1</span>")
});
pre {
  counter-reset: line-numbering;
  background: #2c3e50;
  font-size: 20px;
  border: 2px solid grey;
  width: 450px;
  border-left: 12px solid green;
  border-radius: 5px;
  padding: 14px;
  background-color: #2f2f2f;
  background-image: -webkit-repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  background-image: -moz-repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  background-image: -ms-repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  background-image: -o-repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  background-image: repeating-linear-gradient(top, #444 0px, #444 22px, #2f2f2f 22px, #2f2f2f 44px);
  padding: 0em 1em;
  white-space: pre-wrap;
  word-wrap: break-word;
}

pre .line::before {
  content: counter(line-numbering);
  counter-increment: line-numbering;
  padding-right: 1em;
  /* space after numbers */
  padding-left: 8px;
  width: 1.5em;
  text-align: right;
  opacity: 0.5;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre>
.header-inner {
	width: 1200px;
	margin: 0 auto;
	text-align: center;
	font-size: 24px;
	font-family: 'lato', sans-serif;
}
</pre>

Upvotes: -2

Terry
Terry

Reputation: 66228

As the comments above have mentioned, you will have to use a linear gradient. Since you actually have a top and bottom padding declared (which, when different from your line-height, will interfere with the relative offset of text against the gradient), you will have to set the y position of the background-image:

background-position: 0 14px;

...assuming that your top-padding is 14px (as stated in your example).

Solution 1: Using linear-gradient

linear-gradient is actually very widely supported among modern browsers today (>93% unprefixed, >94% prefixed). For linear-gradient, the start and end color stops are assumed to be the same as the closest breakpoint, so all you need to declare is:

  1. Two breakpoints, color A and color B both at 50% (middle)
  2. Set your background height to 2× the line-height

i.e.:

background-image: linear-gradient(180deg, #eee 50%, #fff 50%);
background-size: 100% 48px;

pre {
  font-size: 20px;
  border: 2px solid grey;
  width: 450px;
  border-left: 12px solid green;
  border-radius: 5px;
  padding: 14px;
  
  /* Fixed line height */
  line-height: 24px;
  
  /* Use linear-gradient for background image */
  background-image: linear-gradient(180deg, #eee 50%, #fff 50%);
  
  /* Size background so that the height is 2x line-height */
  background-size: 100% 48px;
  
  /* Offset the background along the y-axis by top padding */
  background-position: 0 14px;
}
<pre>
.header-inner {
width: 1200px;
margin: 0 auto;
text-align: center;
font-size: 24px;
font-family: 'lato', sans-serif;
}
</pre>

Solution 2: Using repeating-linear-gradient

Using repeating-linear-gradient is very similar to linear-gradient, but remember to declare all color stops (the start and end stops are not assumed):

  1. color A at 0px (start)
  2. color A at 24px (1× line-height)
  3. color B at 24px (1× line-height)
  4. color B at 48px (2× line-height)

i.e.:

background-image: repeating-linear-gradient(
    180deg,
    #eee 0px,
    #eee 24px,
    #fff 24px,
    #fff 48px);

Here is an example:

pre {
  font-size: 20px;
  border: 2px solid grey;
  width: 450px;
  border-left: 12px solid green;
  border-radius: 5px;
  padding: 14px;
  
  /* Fixed line height */
  line-height: 24px;
  
  /* Use repeating-linear-gradient for background image */
  background-image: repeating-linear-gradient(
      180deg,
      #eee 0px,
      #eee 24px,
      #fff 24px,
      #fff 48px);

  /* Offset the background along the y-axis by top padding */
  background-position: 0 14px;
}
<pre>
.header-inner {
width: 1200px;
margin: 0 auto;
text-align: center;
font-size: 24px;
font-family: 'lato', sans-serif;
}
</pre>

Upvotes: 9

Triby
Triby

Reputation: 1757

As @Mr Lister said, use gradients.

.my-pre{
  line-height:1.2em;
  background:linear-gradient(180deg,#ccc 0,#ccc 1.2em,#eee 0);
  background-size:2.4em 2.4em;
  background-origin:content-box;
  
  /* some extra styles*/
  padding:0 20px;
  text-align:justify;
  font-family:calibri,arial,sans-serif;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<pre class="my-pre">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit.
  Voluptate ab pariatur assumenda ipsum exercitationem tempore
  architecto, adipisci, id nihil culpa molestias rerum, dolore alias?
  Fugit eos doloribus dolore, expedita officiis.
</pre>
</body>
</html>

Upvotes: 14

Related Questions