Home > Software design >  How to make a border going left and right like a snake around my articles list?
How to make a border going left and right like a snake around my articles list?

Time:08-18

I want to make a line that go around my articles like a snake that go left and right. To achieve that, I have tried the code below :

.article-container{
    padding: 10px;
    border-top: 5px solid #df9b35;
    border-bottom: 5px solid #df9b35;
}


.article-container.left{
      border-left: 5px solid #df9b35;
      padding-left: 30px;
      border-radius: 50px 0 0 50px;
}


.article-container.right{
      border-right: 5px solid #df9b35;
      padding-right: 30px;
      border-radius: 0 50px 50px 0;
}
<section>
  <div >
    <article>
      <header>
        <h1>Article 1</h1>
        <time datetime="2022-08-18 15:55">18 August</time>
      </header>
      <p>Short description here</p>
    </article>
  </div>
  <div >
    <article>
      <header>
        <h1>Article 2</h1>
        <time datetime="2022-08-18 16:00">18 August</time>
      </header>
      <p>Short description here</p>
    </article>
  </div>
  <div >
    <article>
      <header>
        <h1>Article 3</h1>
        <time datetime="2022-08-18 16:05">18 August</time>
      </header>
      <p>Short description here</p>
    </article>
  </div>
</section>

But as you can see, the problem here is that the border continue all along the container and don't stop before the next border radius. So, I don't have the continuous line that I'm searching for.

CodePudding user response:

A neat way to make this work would be to make use of pseudo-elements like ::before or ::after in which you could display the border with an offset on the sides that you simply can't achieve when relying on the box-model.

It would look like this:

.article-container {
  position: relative;
  padding: 10px;
}

.article-container:not(:last-child) {
  margin-bottom: -5px;
}

.article-container::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  border-top: 5px solid #df9b35;
  border-bottom: 5px solid #df9b35;
}

.article-container.left {
  padding-left: 30px;
}

.article-container.left::before {
  right: 50px;
  left: 0;
  border-left: 5px solid #df9b35;
  border-radius: 50px 0 0 50px;
}

.article-container.right {
  padding-right: 30px;
}

.article-container.right::before {
  left: 50px;
  right: 0;
  border-right: 5px solid #df9b35;
  border-radius: 0 50px 50px 0;
}
<section>
  <div >
    <article >
      <header>
        <h1>Article 1</h1>
        <time datetime="2022-08-18 15:55">18 August</time>
      </header>
      <p>Short description here</p>
    </article>
  </div>
  <div >
    <article >
      <header>
        <h1>Article 2</h1>
        <time datetime="2022-08-18 16:00">18 August</time>
      </header>
      <p>Short description here</p>
    </article>
  </div>
  <div >
    <article >
      <header>
        <h1>Article 3</h1>
        <time datetime="2022-08-18 16:05">18 August</time>
      </header>
      <p>Short description here</p>
    </article>
  </div>
</section>

The relative positioning on all of the .article-container is critical for this to work and the negative bottom margin makes it so that the top and bottom borders are aligned.

CodePudding user response:

Here's a solution where I removed the left and right borders from the divs and added pseudo-elements instead which also contain the border "curves". Takes some tweaking of the positions etc., and (if you want the very end of the line to lead all the way to the side of the container) especially the very last : before element depends on whether it's a left or right element, so you might have to tweak that additionally.

.article-container {
  padding: 10px 0;
  border-top: 5px solid #df9b35;
  border-bottom: 5px solid #df9b35;
  position: relative;
  left: 40px;
  width: calc(100% - 80px);
}

.article-container:nth-child(n 2) {
  margin-top: -5px;
}
.article-container.left:first-child:before {
 position: absolute;
  content: '';
  top: -5px;
  right: -40px;
  height: 100%;
  width: 40px;
  border-top: 5px solid #df9b35;
  }
.article-container.left:after {
  position: absolute;
  content: '';
  top: -5px;
  left: -40px;
  height: 100%;
  width: 40px;
  border-radius: 50px 0 0 50px;
  border-left: 5px solid #df9b35;
  border-top: 5px solid #df9b35;
  border-bottom: 5px solid #df9b35;
}

.article-container.right:after {
  position: absolute;
  content: '';
  top: -5px;
  right: -40px;
  height: 100%;
  width: 40px;
  border-radius: 0 50px 50px 0;
  border-right: 5px solid #df9b35;
  border-top: 5px solid #df9b35;
  border-bottom: 5px solid #df9b35;
}
.article-container.left:last-child:before {
 position: absolute;
  content: '';
  top: 0px;
  right: -40px;
  height: 100%;
  width: 40px;
  border-bottom: 5px solid #df9b35;
  }
<section>
  <div >
    <article >
      <header>
        <h1>Article 1</h1>
        <time datetime="2022-08-18 15:55">18 August</time>
      </header>
      <p>Short description here</p>
    </article>
  </div>
  <div >
    <article >
      <header>
        <h1>Article 2</h1>
        <time datetime="2022-08-18 16:00">18 August</time>
      </header>
      <p>Short description here</p>
    </article>
  </div>
  <div >
    <article >
      <header>
        <h1>Article 3</h1>
        <time datetime="2022-08-18 16:05">18 August</time>
      </header>
      <p>Short description here</p>
    </article>
  </div>
</section>

CodePudding user response:

section {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.article-container {
  padding: 10px;
  width: calc(100% - 2 * 50px);  /* 2 * border-radius */

}

.article-container.left {
  border-left: 5px solid #df9b35;
  padding-left: 30px;
  border-radius: 50px 0 0 50px;
  position: relative;
  left:-25px; /* shift left border-radius/2 */
  border-top: 5px solid #df9b35;
  border-bottom: 5px solid #df9b35;
}

.article-container.right {
/*   border-right: 5px solid #df9b35; */
  padding-right: 30px;
  border-radius: 0 50px 50px 0;
  position: relative;
  right:-25px;  /* shift right border-radius/2 */
  box-shadow: 0px -5px 0px 0px #df9b35, 5px 5px 0px 0px #df9b35;  
  /* this will overlap the other article's border */
}

CodePen

  • Related