У меня есть кнопки, которые отображаются в сетке CSS. Я хотел бы поставить стрелки в пробелах, которые будут похожи на блок-схему. Если невозможно использовать сетку css, можно придумать что-то, что можно реализовать с использованием другой техники. Это stackblitz, который покажет мою реализацию без стрелок между ними. https://stackblitz.com/edit/angular-wipq2r-miu8fl?file=src%2Fapp%2Fproduct-list%2Fproduct-list.component.html
Иллюстрация желаемого результата была бы полезна для понимания вопроса.
@ServeshChaturvedi я добавил иллюстрацию
@isherwood Пожалуйста, посмотрите мой код в stackblitz: stackblitz.com/edit/…
Пожалуйста, проверьте свой код, он просто показывает множество стрелок. И добавьте в свой вопрос достаточно кода, а не стороннего сайта, и убедитесь, что он показывает вашу проблему. Это поможет с тем, как это сделать: stackoverflow.com/help/минимально-воспроизводимый-пример
Как это связано с Font Awesome?
Вы можете использовать псевдоэлементы на кнопках и clip-path для создания необходимых форм стрелок в зависимости от того, является ли это последней кнопкой в строке или нет.






Я бы создал классы, которые можно было бы применять к каждому «шагу» в зависимости от того, куда должна указывать стрелка (вверх, вниз, влево, вправо), а затем использовал бы псевдоселектор ::after для создания элемента стрелки в каждом классе, стилизуя по мере необходимости. .
Смотри ниже.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-gap: 20px;
}
.step {
background-color: blue;
color: white;
padding: 10px;
position: relative;
}
.arrow-right::after {
color: black;
content: '→';
font-size: 20px;
position: absolute;
left: 100%;
top: 50%;
transform: translateY(-50%);
}
.arrow-down::after {
color: black;
content: '↓';
font-size: 16px;
position: absolute;
left: 50%;
top: 100%;
transform: translateX(-50%);
}
.arrow-up::after {
color: black;
content: '↑';
font-size: 16px;
position: absolute;
left: 50%;
bottom: 100%;
transform: translateX(-50%);
}
.arrow-left::after {
color: black;
content: '←';
font-size: 20px;
position: absolute;
right: 100%;
top: 50%;
transform: translateY(-50%);
}<div class = "grid">
<div class = "step arrow-right">Step X</div>
<div class = "step arrow-down">Step X</div>
<div class = "step">Step X</div>
<div class = "step">Step X</div>
<div class = "step arrow-down">Step X</div>
<div class = "step">Step X</div>
<div class = "step arrow-up">Step X</div>
<div class = "step arrow-left">Step X</div>
<div class = "step">Step X</div>
</div>Спасибо тебе за это. Это действительно решило мою проблему
Другой подход — использовать SVG.
Обновление 2 Когда мы вычисляем позицию, нам нужен susbstrat из element.getBoundingClientRect(), getBoundingClientRect().top и getBoundingClientRect().left "обертки"
Идея кладется вся под обертку div
<div #wrapper class = "wrapper">
<svg [attr.width] = "size.width" [attr.height] = "size.height"
xmlns = "http://www.w3.org/2000/svg">
<path *ngFor = "let path of paths" [attr.d] = "path" />
</svg>
<div #bt *ngFor = "let item of procDesc; let i = index" class = "step">
..your buttons..
</div>
</div>
Вы получаете элементы с помощью viewChild и ViewChildren и объявляете массив «путей» и объект с размером обертки
@ViewChildren('bt') items:QueryList<ElementRef>
@ViewChild('wrapper') wrapper:ElementRef
paths:string[]=[]
size = {width:0,height:0}
Затем, когда вы изменяете размер (я использую оператор fromEvent rxjs в стекблиц )
ngOnInit()
{
this.subscription=fromEvent(window,'resize').pipe(
startWith(null),
debounceTime(200)
).subscribe(_=>{
setTimeout(()=>{
this.paths=this.createPath()
const rect=this.wrapper.nativeElement.getBoundingClientRect()
this.size = {width:rect.width,height:rect.height}
})
})
}
ngOnDestroy(){
this.subscription.unsubscribe()
}
Функция createPath похожа на
createPath()
{
const path:string[]=[]
const add=.5; //if stroke-width is even use add=.5 else use add=0
//get the position of "wrapper"
const wrapper=this.wrapper.nativeElement.getBoundingClientRect()
this.items.forEach((x,i)=>{
if (i)
{
/* replace this lines
const ini=this.items.find((_,index)=>index==i-1)
.nativeElement.getBoundingClientRect()
const fin=x.nativeElement.getBoundingClientRect()
*/
//by
const _ini=this.items.find((_,index)=>index==i-1)
.nativeElement.getBoundingClientRect()
const _fin=x.nativeElement.getBoundingClientRect()
const ini = {width:_ini.width,height:_ini.height,
left:_ini.left+window.scrollX,top:_ini.top+window.scrollY}
const fin = {width:_fin.width,height:_fin.height,
left:_fin.left+window.scrollX,top:_fin.top+window.scrollY}
const _ini=this.items.find((_,index)=>index==i-1)
.nativeElement.getBoundingClientRect()
const _fin=x.nativeElement.getBoundingClientRect()
const ini = {width:_ini.width,height:_ini.height,
left:_ini.left-wrapper.left,top:_ini.top-wrapper.top}
const fin = {width:_fin.width,height:_fin.height,
left:_fin.left-wrapper.left,top:_fin.top-wrapper.top}
if (ini.top==fin.top)
{
path.push(`M${ini.left+ini.width+add} ${ini.top+ini.height/2+add}
H${fin.left-add}
M${fin.left-7-add} ${fin.top+fin.height/2-4-add}
L${fin.left-add} ${fin.top+fin.height/2+add}
M${fin.left-7-add} ${fin.top+fin.height/2+4+add}
L${fin.left-add} ${fin.top+fin.height/2+add}`)
}
else
{
const step=6; //(fin.top-ini.top-ini.height)/2
path.push(`M${ini.left+ini.width/2+add} ${ini.top+ini.height+add}
V${ini.top+ini.height+step+add}
H${fin.left+fin.width/2+add}
V${fin.top-add}
M${fin.left+fin.width/2+4+add} ${fin.top-7-add}
L${fin.left+fin.width/2+add} ${fin.top-add}
M${fin.left+fin.width/2-4-add} ${fin.top-7-add}
L${fin.left+fin.width/2+add} ${fin.top-add}`
)
}
}
})
return path
}
Поскольку стрелки — это просто визуальные подсказки, мы можем использовать псевдоэлементы для их изображения.
Вы можете «нарисовать» линии и наконечники стрелок, поместив псевдоэлемент after на элемент с черным цветом фона и обрезав его с помощью clip-path.
Нам нужны два clip-path, один для горизонтальных линий/стрелок и один для пути, идущего от конечного элемента в каждой строке к первому в следующей строке.
В этом фрагменте используются настройки некоторых переменных CSS, чтобы упростить их изменение в соответствии с конкретным вариантом использования.
Вот результат:
* {
margin: 0;
padding;
0;
box-sizing: border-box;
}
.container {
--gap: 10vmin;
/* set this to what you want the gap to be - absolute units */
display: grid;
gap: var(--gap);
grid-template-columns: 1fr 1fr 1fr;
width: 100vw;
/* set this to whatever you want */
padding: var(--gap);
}
.container>* {
border: solid 1px black;
width: 100%;
--ar: 3 / 1;
/* set this to what you want the aspect ratio of a button to be */
aspect-ratio: var(--ar);
position: relative;
}
.container>*::after {
content: '';
width: var(--gap);
--arrow: 20px;
/* set this to the height of the arrowhead */
--ha: calc(var(--arrow) / 2);
/* half the height of an arrowhead */
--line: 2px;
/* set this to the width (height) of the lines */
--hl: calc(var(--line) / 2);
/* half the height of a line */
height: var(--arrow);
background-color: black;
clip-path: polygon(0 calc(var(--ha) - var(--hl)), calc(100% - var(--ha)) calc(var(--ha) - var(--hl)), calc(100% - var(--ha)) 0, 100% 50%, calc(100% - var(--ha)) 100%, calc(100% - var(--ha)) calc(var(--ha) + var(--hl)), 0 calc(var(--ha) + var(--hl)));
position: absolute;
top: 50%;
transform: translateY(-50%);
right: calc(-1 * var(--gap));
}
.container>*:nth-child(3n)::after {
width: calc(200% + (2 * var(--gap)) + var(--line));
height: var(--gap);
transform: translateY(0);
top: 100%;
right: calc(50% - (var(--hl)));
clip-path: polygon( 100% 0, 100% calc(50% + var(--hl)), calc(var(--ha) + var(--hl)) calc(50% + var(--hl)), calc(var(--ha) + var(--hl)) calc(100% - var(--ha)), var(--arrow) calc(100% - var(--ha)), var(--ha) 100%, 0 calc(100% - var(--ha)), calc(var(--ha) - var(--hl)) calc(100% - var(--ha)), calc(var(--ha) - var(--hl)) calc(50% - var(--hl)), calc(100% - var(--line)) calc(50% - var(--hl)), calc(100% - var(--line)) 0);
}
.container>*:last-child::after {
display: none;
}<div class = "container">
<button></button><button></button><button></button><button></button><button></button><button></button><button></button><button></button><button></button>
</div>
См. Как спросить. Ваш вопрос нуждается в доработке. Вам нужно показать код здесь.