shabunc
shabunc

Reputation: 24741

Is it possible to draw vertical lines via css gradients starting from arbitrary point?

I can draw a line in background using linear-gradient or repeating-linear-gradient, for instance:

   background-color: linen;
   background-image: repeating-linear-gradient(90deg, black, black 1px, linen 1px, linen 100px);
   background-position: 100px;

I'l get something like: enter image description here

My question would be - what will be the best way to draw such lines from some arbitrary point, not from the very top (or very bottom), say, I want to draw line from the middle of container to the top?

Is it possible at all?

What have I've tried so far: I've checked wether background-size or background-position can change this but still no luck.

Upvotes: 3

Views: 5614

Answers (4)

Asons
Asons

Reputation: 87191

As the linear-gradient creates an image and we can treat it as one, so a very simple way is to combine it with background-size/background-repeat.

div {
  width: 700px;
  height: 100px;
  background-color: linen;
  background-size: 50px 50px;
  background-repeat: repeat-x;
  background-image: linear-gradient(to right, black 1px, transparent 1px, transparent),
                    linear-gradient(to right, black 1px, transparent 1px, transparent),
                    linear-gradient(60deg, transparent 25px, black 25px, transparent 26px, transparent);
  background-position: left 30px top,
                       left 5px bottom,
                       left 5px center;
}
<div></div>

Upvotes: 4

I haz kode
I haz kode

Reputation: 1635

This is more of a hack.

it breaks the gradient vertically into ten 10% sections.

You toggle each section by editing the alpha channel in the rgba to either 1 or 0

It's not supported in Edge and IE.

.container {
  height: 50px;
  background-color: linen;
}

.grad {
  height: 100%;
  background-image: repeating-linear-gradient(90deg, black, black 1.5px, linen 1.5px, linen 100px);
}

.middle-to-bottom {
  -webkit-mask-image: linear-gradient(
  rgba(0, 0, 0, 1)10%,
  rgba(0, 0, 0, 1)20%, 
  rgba(0, 0, 0, 1)30%, 
  rgba(0, 0, 0, 1)40%,
  rgba(0, 0, 0, 0)50%,
  rgba(0, 0, 0, 0)60%, 
  rgba(0, 0, 0, 0)70%,
  rgba(0, 0, 0, 0)80%, 
  rgba(0, 0, 0, 0)90%, 
  rgba(0, 0, 0, 0)100%);
}

.middle-to-top {
  -webkit-mask-image: linear-gradient( 
  rgba(0, 0, 0, 0)10%,
  rgba(0, 0, 0, 0)20%, 
  rgba(0, 0, 0, 0)30%, 
  rgba(0, 0, 0, 0)40%,
  rgba(0, 0, 0, 0)50%,
  rgba(0, 0, 0, 1)60%, 
  rgba(0, 0, 0, 1)70%,
  rgba(0, 0, 0, 1)80%, 
  rgba(0, 0, 0, 1)90%, 
  rgba(0, 0, 0, 1)100%);
}

.middle {
  -webkit-mask-image: linear-gradient( 
  rgba(0, 0, 0, 0)10%,
  rgba(0, 0, 0, 0)20%, 
  rgba(0, 0, 0, 0)30%, 
  rgba(0, 0, 0, 1)40%,
  rgba(0, 0, 0, 1)50%,
  rgba(0, 0, 0, 1)60%, 
  rgba(0, 0, 0, 0)70%,
  rgba(0, 0, 0, 0)80%, 
  rgba(0, 0, 0, 0)90%, 
  rgba(0, 0, 0, 0)100%);
}


.random {
  -webkit-mask-image: linear-gradient( 
  rgba(0, 0, 0, 0)10%,
  rgba(0, 0, 0, 0)20%, 
  rgba(0, 0, 0, 1)30%, 
  rgba(0, 0, 0, 1)40%,
  rgba(0, 0, 0, 0)50%,
  rgba(0, 0, 0, 0)60%, 
  rgba(0, 0, 0, 0)70%,
  rgba(0, 0, 0, 1)80%, 
  rgba(0, 0, 0, 1)90%, 
  rgba(0, 0, 0, 0)100%);
}

h4 {
  text-align:center;
  margin:.5em auto;
  padding:2px;
}
<h4>middle to top</h4>
<div class="container">
  <div class="grad middle-to-bottom"></div>
</div>

<h4>middle to bottom</h4>
<div class="container">
  <div class="grad middle-to-top"></div>
</div>

<h4>middle</h4>
<div class="container">
  <div class="grad middle"></div>
</div>

<h4>random</h4>
<div class="container">
  <div class="grad random"></div>
</div>

Upvotes: 1

tao
tao

Reputation: 90103

Use children, set different backgrounds to each child while controlling the ratio between them.

In the example below, I use your background but control the "origin", which is not "normally" possible using repeating-linear-gradient.

repeating-linear-gradient() takes a direction as a first parameter.

The direction can be an angle (as you specified it), a side (to left, to right...) or a corner (to left bottom,...). This means it starts from the opposite side/corner. It can't start from an arbitrary point inside the element.

But this doesn't mean you cannot have one or more children starting background from their joined sides towards the outside:

.custom-origin {
  display: flex;
  flex-wrap:wrap;
  height: 100vh;
}
.custom-origin div {
  background-image: repeating-linear-gradient(to left, black, black 1px, linen 1px, linen 100px);
  flex-grow: 1;
  min-width: 33.33%;
}
.custom-origin div:nth-child(2) {
  background-image: repeating-linear-gradient(to right, white, white 99px, black 1px, black 100px);
}
.custom-origin div:first-child {
  max-width: 33.33%; /* this sets the position of your origin. 
                     * If not set, it will be the exact half of the parent,
                     * in this example 
                     */ 
}
.custom-origin .full {
  min-width: 100%;
  background-image: none;
  background-color: linen;
}
body {
  margin: 0;
}
<div class="custom-origin">
  <div></div>
  <div></div>
  <div class="full"></div>
</div>

By controlling the size of children you can control how the background image is applied. To outline the "position", I changed one of the children's linen to white.

Upvotes: 1

cjl750
cjl750

Reputation: 4629

Use a double gradient, with the first one being a vertical gradient that goes from your background color to transparent from bottom to top, and the second one being the repeating linear gradient going right-to-left.

div {
  width: 700px;
  height: 100px;
  background: linear-gradient(to top, ivory, ivory 50px, transparent 50px, transparent), repeating-linear-gradient(to right, black, black 1px, ivory 1px, ivory 100px);
}
<div></div>

Upvotes: 1

Related Questions