Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Child take width % from parents parent

Tags:

css

Is the following result possible with CSS:

So that li.item takes 50% of the width of div.wrapper, not the ul.list (which is extremly long). I've added a snippet of a basic setup. Any ideas on the matter are appreciated (please keep in mind I'm looking for CSS options). A jsfiddle playground link: http://jsfiddle.net/6o8t9t8L/

.wrapper {
    width: 400px;
    overflow-y: hidden;
    overflow-x: scroll;
    border: 1px solid black;
}
.list {
    list-style-type: none;
    border: 1px solid red;
    width: 2000px;
}
.item {
    display: inline-block;
    height: 200px;
    width: 50%;
    border: 1px solid green;
}
<div class="wrapper">
    <ul class="list">
        <li class="item"></li>
        <li class="item"></li>
        <li class="item"></li>
        <li class="item"></li>
    </ul>
</div>
like image 933
Peeter Avatar asked Jan 12 '15 16:01

Peeter


People also ask

How can kids make parent element width?

Method 1: First method is to simply assign 100% width and 100% height to the child div so that it will take all available space of the parent div. Consider this HTML for demonstration: HTML.

What is width inherit?

width:inherit inherits width that defined by parent. This makes child width 25%, but if I redefine it with width:100% it will define width of child 50%. I see. So inherit copies the literal expression rather than the value.

Why did the width collapse in the percentage width child element in an absolutely positioned parent on Internet Explorer 7?

Its width will be worked out based on the pixel width of its content and will be calculated after the contents are rendered. So at the point, IE encounters and renders your relatively positioned div its parent has a width of 0 hence why it itself collapses to 0.


1 Answers

I believe there are some 'workaround' solutions to your issue, so I'll pour in some of my ideas, maybe it will help you out a bit.

Idea 1: Position absolute and a bunch of :nth-child selectors

In order to make the .item have their width relative to .list wrapper, you can absolute position these items, and set .list wrapper to position relative, so that the .item width will be calculated based on .list width.

The major downfall of this idea would be that you have to position these elements next to each, like using the left property, but passing it like a loop:

  • first item will have left: 0;
  • second item will have left: 50%;
  • third item will have left: 100%;
  • and so on...+50% to the next items

You can either pour in a bunch of :nth-child(n), each with +50% left prop. from each other, OR use some sass stuff to make it faster.

Check out the demo here & sass demo here

*,
*:after,
*:before {
  box-sizing: border-box;
}
.wrapper {
  width: 400px;
  overflow-y: hidden;
  overflow-x: scroll;
  border: 1px solid black;
  /*make the grandparent, .wrapper, relative, so that the grandchilds, .item, 
    will calculate their width based on this width*/
  position: relative;
}
.list {
  list-style-type: none;
  border: 1px solid red;
  width: 2000px;
  margin: 50px 0;
  padding: 0;
  /*since everyone has position absolute, theres no content flow, so a fixed height
    has to be supplied*/
  height: 200px;
}
.item {
  width: 50%;
  border: 1px solid green;
  position: absolute;
  left: 0;
  /*you can set a height here, or position them like I did bellow*/
  top: 51px;
  bottom: 51px;
}
/*now the fun part starts
somehow these .items have to have left: +50% for each of them, like a loop somehow,
so you can either pour in a lot of nth-child(), for how many children you think this
list is going to have, or use sass to write it faster like i did here: 
*/

.item:nth-child(1) {
  left: 0;
}
.item:nth-child(2) {
  left: 50%;
}
.item:nth-child(3) {
  left: 100%;
}
.item:nth-child(4) {
  left: 150%;
}
.item:nth-child(5) {
  left: 200%;
}
.item:nth-child(6) {
  left: 250%;
}
.item:nth-child(7) {
  left: 300%;
}
.item:nth-child(8) {
  left: 350%;
}
.item:nth-child(9) {
  left: 400%;
}
.item:nth-child(10) {
  left: 450%;
}
.item:nth-child(11) {
  left: 500%;
}
<div class="wrapper">
  <ul class="list">
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
  </ul>
</div>

Idea 2: Display: flex

Using display: flex on .wrapper, will allow you to have the widths of the .item to be relative to their grandparent.

The major downfall of this idea would be that the width of .list element, will be overwritten by the width of .wrapper, no matter if you specify it or not. However, not all is lost, if you need that specific width for some styling, you can specify it, and use some pseudo classes with width: inherit, so they'll stretch to whatever width you specified in the first place.

Check out the demo here

*,
*:after,
*:before {
  box-sizing: border-box;
}
.wrapper {
  width: 400px;
  overflow-y: hidden;
  overflow-x: scroll;
  border: 1px solid black;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  /*bring on the awesomeness*/
  margin: 20px;
}
.list {
  list-style-type: none;
  /*border: 1px solid red;*/
  /*you can keep this defined width, items will calculte their width
    based on .wrapper class, wich will overwrite this classes width,
    however if you have some use for this width, consider using :after, :before
    classes like I did bellow, with .list:before*/
  position: relative;
  z-index: 1;
  width: 2000px;
  white-space: nowrap;
  margin: 20px 0;
  padding: 0;
  font-size: 0;
  /*display inline block extra spacing ....*/
}
.list:before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: inherit;
  /*it will inherit the width you set above*/
  border: 1px solid red;
}
.item {
  display: inline-block;
  vertical-align: top;
  height: 200px;
  width: 50%;
  border: 1px solid green;
  font-size: 16px;
  /*bump back the font-size*/
}
<div class="wrapper">
  <ul class="list">
    <li class="item">a</li>
    <li class="item">b</li>
    <li class="item">c</li>
    <li class="item">d</li>
  </ul>
</div>
like image 65
RGLSV Avatar answered Oct 28 '22 08:10

RGLSV