CSS - 在动态大小的盒子之间画线

Posted

技术标签:

【中文标题】CSS - 在动态大小的盒子之间画线【英文标题】:CSS - drawing lines between dynamically sized boxes 【发布时间】:2021-10-09 09:51:29 【问题描述】:

我使用 CSS 创建了类似的东西。 这里的棘手之处在于,如果文本太长,框的高度可能会发生变化。

所以,我不知道如何使虚线始终以这种方式运行,因为框的大小是动态的。 (从第一个框的中间到下一个框的中间应该总是有一条线)

这是我现在使用的 html 和 CSS。

我实际上在使用 SCSS 和 React(我正在打印“行”div 4 次)

 <div class="wrapper">
   <div class="row">
     <div class="bordered-div"></div>
     <div class="step">
       <img src="placeholder.svg"  />
       <div class="step-text">
         <div class="step-title">Title</div>
         <div class="step-description">Decsription...</div>
       </div>
     </div>
   </div>
 </div>

.wrapper 
 display: flex;
 flex-direction: column;
 align-items: center;
 gap: 30px;

 .row 
   display: flex;
   position: relative;

   &:last-child 
     .bordered-div 
       height: 0;
     
   

   .bordered-div 
     position: absolute;
     top: 50%;
     left: -50px;
     width: 50px;
     border-top: 1px dashed #c2c9d5;
     border-left: 1px dashed #c2c9d5;
     height: calc(100% + 30px);
   

   .step 
     background: blue;
     min-height: 118px;
     width: 322px;
     padding: 20px;
     border-radius: 8px;
     display: flex;
     gap: 20px;
     filter: drop-shadow(0px 0px 4px rgba(183, 183, 183, 0.15))
       drop-shadow(0px 4px 4px rgba(217, 217, 217, 0.25));

     svg 
       width: 16px;
       align-self: center;
       flex: none;
     

     .step-title 
       font-size: 0.875rem;
       font-weight: 600;
     

     .step-description 
       font-size: 0.875rem;
     
   
 

【问题讨论】:

【参考方案1】:

这是一个带有最少标记的快速概念证明。 我相信你不需要任何额外的空 div。

li 
  position: relative;
  list-style: none;
  max-width: 77ch;
  background-color: #ccc;
  border-radius: 1em;
  padding: 1em;
  margin-bottom: 1em;
  z-index: 2;


li:before 
  content:'';
  position: absolute;
  display: block;
  height: 0px;
  width: 2em;
  top: 50%;
  left: -2em;
  border-top: 1px red dashed;
  z-index: -1;


li:after 
  content:'';
  position: absolute;
  display: block;
  height: calc(100% + 1em);
  width: 0px;
  top: -0.5em;
  bottom: -0.5em;
  left: -2em;
  border-left: 1px red dashed;
  z-index: -1;


li:first-child:after 
  top: 50%;


li:last-child:after 
  bottom: 50%;


li:first-child:after,
li:last-child:after 
  height: calc(50% + 0.5em);
 
<ul>
  <li>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
  </li>
  <li>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
  </li>
  <li>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
       <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p> 
  </li>
  <li>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae repudiandae minima, eligendi vero et eveniet magni sit facilis, dolores tempora cumque, atque deleniti dolore hic in architecto ducimus earum explicabo?</p>
  </li>  
</ul>
首先,我为每个li 创建一个before 伪元素。 此伪元素用于创建水平线。我使用边框来创建虚线效果,但您可以使用线性渐变或其他任何东西。 然后,我为每个li 创建一个after 伪元素。 此伪元素用于创建垂直线。您需要调整第一个和最后一个的高度。

编辑:

在示例中,li 之间的边距为1em。 这里也用到了这个1em 值:

li:after 
  top: -0.5em; // <-- 1em / 2
  bottom: -0.5em; // <-- 1em / 2


li:first-child:after,
li:last-child:after 
  height: calc(50% + 0.5em); // <-- calc(50% - 1em / 2)

如果您更改 li 之间的边距,您应该相应地更新这些值。当您使用 sass 时,只需使用一个变量就可以了。

【讨论】:

哇,这太棒了!非常感谢:) 如何在不破坏边框的情况下增加 li 元素之间的边距?谢谢 查看我的编辑,您用于边距的值对其他属性有直接影响。【参考方案2】:

您想要的输出类似于流程图。通过这个类比,您可以使用有序列表&lt;ol&gt; 作为包含行的包装器。然后对每个&lt;li&gt; 应用边距。最后,将盒子内容包裹在 &lt;p&gt; 中,并将其设置为看起来像一个盒子。

这是一个简单的示例,其中每个框都有不同的高度。您只需要根据自己的需要进行调整即可。

/* RESET STYLES & HELPER CLASSES
–––––––––––––––––––––––––––––––––––––––––––––––––– */

* 
  padding: 0;
  margin: 0;
  box-sizing: border-box;


ol 
  list-style: none;


body 
  padding: 24px;


.box 
  position: relative;
  padding: 24px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);



/* FLOWCHART
–––––––––––––––––––––––––––––––––––––––––––––––––– */

.wrapper 
  position: relative;
  width: 80%;
  margin-left: auto;


.wrapper::before 
  content: "";
  position: absolute;
  left: -20px;
  height: calc(100%);
  border: 1px dashed;
  );


.wrapper li+li 
  margin-top: 20px;


.box-content 
  font-weight: normal;
  background: yellow;
  border-radius: 8px;


.box-content::before 
  content: "";
  position: absolute;
  top: 50%;
  left: 2px;
  transform: translate(-100%, -50%);
  width: 20px;
  border: 1px dashed;
  z-index: -1;
<ol class="wrapper">
  <li>
    <p class="box-content box">One line</p>
  </li>
  <li>
    <p class="box-content box">Two lines<br>Two lines</p>
  </li>
  <li>
    <p class="box-content box">Three lines<br>Three lines<br>Three lines</p>
  </li>
  <li>
    <p class="box-content box">Four lines<br>Four lines<br>Four lines<br>Four lines</p>
  </li>
</ol>

【讨论】:

以上是关于CSS - 在动态大小的盒子之间画线的主要内容,如果未能解决你的问题,请参考以下文章

CSS3教程盒子旋转动态图

【8】CSS盒子模型、样式继承和默认样式

Web前端开发笔记——第三章 CSS语言 第五节 盒子模型

弹性盒子

CSS盒子模型

CSS 盒子模型