akcasoy
akcasoy

Reputation: 7215

How to make a border left with custom bullet for my list, in a gradient style?

This is what I want to achieve:

enter image description here

Items with white background are my list items. On the left side I want to have a border, with custom bullets (custom, since we cannot change the default list bullet color -black- AFAIK). The upper part of the border should have a gradient color, from transparent to grey color for instance. As you also see in the pic, the length of the border should be longer than the actual list height (until the plus button, not till the last item ends.)

I have actually achieved some parts but i would like to know a better, cleaner way of doing it.

This is what I have so far: https://jsfiddle.net/6esLm8q1/

.list {
  list-style: none;
  border-width: 2px;
  border-style: solid;
  border-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(179,179,179)) 0 0 0 1;
}

.item {
  margin-bottom: 1em;
  margin-left: -1.7em;
}

.item::before {
  content: "\2022";
  color: grey;
  font-weight: bold;
  display: inline-block; 
  width: 1em;
  margin-left: -1em;
}
<ul class="list">
<li class="item">
Test1
</li>
<li class="item">
Test2</li>
</ul>

<button>Plus
</button>

Problems are still: Aligning of bullets to item text, even if I align the bullets on the border, when I resize the window, the bullets slides to left or right slightly.

The gradient line is far more transparent at the beginning, not actually like in the "Target" pic. And the border ends where the list items end, so it does not reach until the button.

I appreciate any help till I get something close to my target pic!

Upvotes: 1

Views: 971

Answers (3)

Blue
Blue

Reputation: 365

Is it critical to be plain css? From my point of view you're trying to solve the issue with the wrong instruments.

What if you split the element, making the line on the left and the bullet with separate elements, positioned absolutely in the padding region of the container, and the content in subcontinent?

Something like this:

body {
  background-color: #ededed;
}

.tail {
  border-left-style: solid;
  border-left-width: 2px;
  border-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(179,179,179)) 0 0 0 1;
  height: 20px;
  margin-left: 20px;
}

.list {
  font-size: 20px;
  color: rgba(179,179,179);
  list-style: disc;
  border-left: 2px solid rgba(179,179,179);
  margin: 0 0 0 20px;
  box-sizing: border-box;
  padding-bottom: 20px;
  padding-left: 15px;
}

.item {
  margin-bottom: 5px;
}

.item > div {
  color: #555;
  background-color: white;
  padding: 5px;
  font-size: 14px;
  font-family: sans;
  border-radius: 5px;
}

button {
  border-radius: 50%;
  background-color: #b30920;
  border: none;
  color: white;
  box-sizing: border-box;
  padding: 0;
  width: 40px;
  height: 40px;
  overflow: hidden;
  vertical-align: top;
  font-size: 33px;
  margin: 0;
}
<div class="tail"></div>
<ul class="list">
  <li class="item"><div>Test1</div></li>
  <li class="item"><div>Test2<br>test</div></li>
</ul>

<button>+</button>

Upvotes: 0

andreas
andreas

Reputation: 16946

I think your solution is already pretty good. I would create the circles with border-radius, as you have more control over the sizing and position.

Here is an example:

.list {
  list-style: none;
  border-width: 2px;
  border-style: solid;
  border-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(179, 179, 179)) 0 0 0 1;
  margin: 0 0 0 1em;
}

.item {
  position: relative;
}

.item:before {
  position: absolute;
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: grey;
  left: -2.75em;
  top: .4em;
}

button {
  display: inline-block;
  width: 2em;
  height: 2em;
  margin: -.2em 0 0 .25em;
  border-radius: 50%;
  background: #c00;
  color: white;
  border: none;
}
<ul class="list">
  <li class="item">
    <p>Test1<br>test with line break</p>
  </li>
  <li class="item">
    <p>Test2<br>test with<br>two line breaks</p>
  </li>
</ul>
<button>+</button>


<ul class="list">
  <li class="item">
    <p>Test1</p>
  </li>
  <li class="item">
    <p>Test2</p>
  </li>
</ul>
<button>+</button>

Upvotes: 1

wlh
wlh

Reputation: 3515

You got yourself 99% there. For the linear-gradient, if you define the end-point to be lower than 100%, then you get it to fade earlier. Otherwise, it calculates the end point to be 100% and thus half of your border looks faded.

For the before psuedo-element, since in your markup you put a p tag within each li, you should put the pseudo-element on the p tag itself.

See the snippet below.

.list {
  list-style: none;
  border-width: 2px;
  border-style: solid;
  border-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%,  rgba(179,179,179) 40%) 0 0 0 1; /* add % to have gradient end earlier than end */
}

/* add before pseudo-element on p tag (since you include it in your markup */
.item>p:before {
  content: "\2022";
  color: grey;
  font-weight: bold;
  margin-left: -2.7em;
}
<ul class="list">
    <li class="item">
        <p>
            Test1
        </p>
    </li>
    <li class="item">
        <p>
            Test2
        </p>
    </li>
</ul>

<button>Plus</button>

Upvotes: 1

Related Questions