1

I am trying to have an angular component that can dynamically position and resize div elements depending on how many div elements are to be displayed. This is what I have achieved so far.

EDIT: If you checkout my stackblitz example I am using display: flex (thus flexbox). The issue I am having is how can I make sure that a row will at most only have 3 divs and then wrap to the next line and that the divs length will always be the same?

.

EDIT 2: My goal is that when there is one or two divs the length of the div is half that of the container. That is why I put a 'ruler' at the top in the image below. If there are more than 2 divs the length of the divs should be 1/3 of the length of the container. And a row should be filled by three divs before wrapping to the next row.

Below is a visual representation of what I am trying to achieve:

All the divs in a particular set are of the same width and height.

I see how I can hack around by using calc() in width but then I will have to pass the number of divs variable to my css file. Also I am aware that using Multiple conditions in ngClass - Angular 4 is an option, but I would like to use that if I did not have any other option.

How can I achieve what I am trying to achieve with css only (if possible)? If it is not possible to use css only I will gladly take any other recommendation.

YulePale
  • 6,688
  • 16
  • 46
  • 95
  • Have you considered using a stylistic package like bootstrap? Or using `display: flex` ? Or using a directive rather than a full component? – Dane Brouwer Feb 07 '20 at 06:55
  • My current example in [stackblitz](https://stackblitz.com/edit/angular-24gbi5?file=src%2Fapp%2Fapp.component.html) I am using `display: flex`. – YulePale Feb 07 '20 at 06:58
  • Definitely, use flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/ – adrisons Feb 07 '20 at 07:01
  • What's wrong with your current implementation, and have you considered bootstrap (It is a CSS package)? @YulePale, – Dane Brouwer Feb 07 '20 at 07:03
  • 1
    @DaneBrouwer My current implemetation is static not dynamic. If I reduce the div elements to one it won't work as I want it to. From what I am seeing, I think I will have to use ng-class with multiple conditions. My problem is not that flexbox is not working, it is. My problem is that I am trying to make it dynamic. – YulePale Feb 07 '20 at 07:08
  • You could use `min-width: calc(100%/3.1);`? – Dane Brouwer Feb 07 '20 at 07:10
  • @DaneBrouwer I have tried that. Still not getting my desired results. I will just use conditional classes and see how it goes if it works I will post the answer here. Thank you for your help. – YulePale Feb 07 '20 at 07:16
  • @YulePale, Can you check my answer for your issues https://stackblitz.com/edit/angular-24gbi5?file=src%2Fapp%2Fapp.component.html – R.G.Krish Feb 07 '20 at 07:17
  • 1
    @YulePale [Found a link that might be useful](https://stackoverflow.com/questions/8720931/can-css-detect-the-number-of-children-an-element-has) – Dane Brouwer Feb 07 '20 at 07:24
  • @Kitta It works, but not completely. My goal is that when there is one div or two divs the size of the div is half that of the container. – YulePale Feb 07 '20 at 07:24
  • @YulePale, can checkout my update link. https://stackblitz.com/edit/angular-utfkgg – R.G.Krish Feb 07 '20 at 08:00

2 Answers2

1

First make flex container with

.container1 {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

Second use calc() to specify items width

.item {
  width: calc(33.33% - 0px);
}

Third specify first and second child behavior. They should grow, but max-width: 50%

.item:first-child, .item:nth-child(2) {
  flex-grow: 1;
  max-width: 50%;
}

.container1 {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  outline: dashed red 1px;
  margin: 10px 0
}

.item {
  height: 100px;
  background-color: green;
  outline: 1px dashed blue;
  width: calc(33.33% - 0px);
}

.item:first-child, .item:nth-child(2) {
  flex-grow: 1;
  max-width: 50%;
}
<div class="container1">
  <div class="item"></div>
</div>

<div class="container1">
  <div class="item"></div>
  <div class="item"></div>
</div>

<div class="container1">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

<div class="container1">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

<div class="container1">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

<div class="container1">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

<div class="container1">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

<div class="container1">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
Aleksandr Belugin
  • 2,149
  • 1
  • 13
  • 19
0

Checkout sample working copy Check the flex will slove the above issues i guess.

.parent {
  display:flex; 
  justify-content:space-around; 
  flex-wrap:wrap;
}

.option-box{
  width:40%;
  border: 1px blue solid;
  margin: 3px
}
@media screen and (max-width: 600px) and (min-width: 301px) {
  .option-box {
    width:30%;
  }
}
@media screen and (max-width: 300px) {
  .option-box {
    width:100%;
  }
}

Flex

enter image description here

R.G.Krish
  • 487
  • 5
  • 22