3

Update 2

Following @kidconcept's new update about using the table tag, I have modified it to make a centered Table Timeline. Note: copy-pasting @kidconcept's into a local project (not on JS Fiddle) did not have this property. I also added css selectors to make changing direction easier.


Thank you for considering my question.

I am trying to make a custom row. What I want to achieve is describe in more detail under the headings description.

In addition I am including a JS Fiddle, which gets me close (maybe) to what I want to achieve (e.g. I put some work in).

I don't really get CSS3 that well, and the tutorials at W3-schools really only cover basics, however a deeper understanding of the difference between display options and what float actually does to the object is not readily given.

So I appreciate your assistance and am eager to learn from you :)


Description

JS Fiddle: A tri-element row with fixed size middle element

I am trying to make a row which contains exactly three elements. I want the middle element to have a fixed size and be centered. I want the other two elements (left / right) to have a fixed spacing to the middle element, but be responsive in size, see below:

enter image description here

In addition, I would like to stack these rows with a fixed spacing:

enter image description here

As well as be responsive to a small window size:

enter image description here

Update

Using the answer from @kidconcept you can make a reasonable timeline.

enter image description here

Community
  • 1
  • 1
SumNeuron
  • 4,850
  • 5
  • 39
  • 107

3 Answers3

3

UPDATE: I think this is more easily solved with a table. Simply create a table with three columns and give a fixed width to the middle column.

<table>
<tr>
  <td></td>
  <td class="middle"></td>
  <td></tr>
</table>

td {
  background-color: tomato;
  padding: 2rem;
}

.middle {
  width: 10rem;
}

Table Fiddle

https://jsfiddle.net/botbvanz/2/


Problematic Flex method: flex. Learn more about flex here.

<section class="tri-element-rows">
  <div class="left-element"></div>
  <div class="middle-element"></div>
  <div class="right-element"></div>
</section>

html, body {
  height: 100%
}
section {
  display: flex;
  height: 50%;
}

div.middle-element {
  width: 15rem;
  height: 10rem;
}

div.left-element,
div.right-element {
  flex-grow: 1;
}

div {
  background-color: coral;
  margin: 1rem;
}

To achieve the effect simply put three elements within a display: flex box. Set the middle elements width to be fixed, in this case 15rem. Then give the left/right elements flex-grow: 1, which indicates they should fill the remaining space equally. Give all the divs a fixed margin, in this case 1rem.

For the heights, I'm not sure I understood your requirements exactly, but if you want the height of the inner divs to respond to the window you can set their height to be a % of the parent container. For this trick to work you need to remember to set the height of html and body to 100% (this gives them something to be a percentage of. In this case i set the section-height to be 50%, which means that two rows will always fill the screen. One other gotcha is that if you set a padding or a border to the section element, the element will become 50% plus the padding and border. To avoid this, set box-sizing: border-box on the section tag.

Here is a fiddle: https://jsfiddle.net/ksgd6r11/

kidconcept
  • 509
  • 6
  • 13
  • thank you for your supportive comment and helpful post. To clarify what I meant in regards to the variable height is shown in the JS Fiddle in my original post (e.g. the text drops down). Shrinking the window width on your Fiddle does not have this property (but it isn't the most important). While adding text to JS Fiddle (to resemble mine) works, the text is offset when I embed it in my code.... Further, adding text shifts the middle element's position. How can this be fixed? – SumNeuron Feb 10 '17 at 12:48
  • yeah, something like that.... if you do just a bit more editing, you can get this https://jsfiddle.net/SumNeuron/t1j1snxu/4/ . However, while this renders in the JSFiddle, it behaves differently when I run it locally.... – SumNeuron Feb 11 '17 at 06:36
  • Also, open the JS Fiddle I linked above on your phone (or a small screen) and you will see that the middle element no longer stays in the middle. – SumNeuron Feb 11 '17 at 09:11
  • it could be inconsistency with the flex implementation. Actually I should have suggested a table layout. I'll update the answer. – kidconcept Feb 12 '17 at 07:13
  • I like the table idea, however how can we guarantee that the middle element is always dead center? – SumNeuron Feb 12 '17 at 10:44
  • see my new update. It seems to be working both locally and on JSFiddle, with the exception of the date being not as close to the image as the title for some reason.... It also, unfortunately, shoves the text behind the timeline when the screen is very small. Anyway to over come this? It also suffers from having long text mess up the size – SumNeuron Feb 12 '17 at 11:47
  • You only need one table with multiple rows, simply your html and it will help you track down layout bugs more easily. About the text under the image. You could try setting position:relative with z-index to get the text over the image, but that won't help read the text at all. You should make the image smaller with a media query. About the date not lining up, that's probably some margin or padding collapsing. try setting all margin and padding to 0, * {margin:0;padding:0} to see if that fixes it. Use chrome developer tools to poke around at the elements and see what's causing what. – kidconcept Feb 12 '17 at 15:48
2

i would suggest use a framework


It saves a lot of time and you can focus on logic

they all have offset as one of their classes

However how we achieve the same in Bootstrap is

<div class="container">
    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <div class="col-xs-2 col-xs-offset-3 col-sm-2 col-sm-offset-3 col-md-2 col-md-offset-3 col-lg-2 col-lg-offset-3">
        </div>
        <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2"></div>

        <div class="col-xs-2 col-sm-2 col-md-2 col-lg-2"></div>
    </div>
</div>

what it does it gives a padding left to the left most block

In your case.check this(jsfiddle)

or rather

div.block{
  width:32%;
  height:50px;
  border:1px solid black;
  float:left;
  margin:2px;
}
div.block-2{
  width:31%;
  height:50px;
  float:left; border:1px solid black;
  margin:2px;
}
div.margin-l{
  margin-left:50px;
}
div.section-2{
  margin:0 auto;
  width:60%;
}
<section class="tri-element-rows">
 <div class="block">
 
 </div>
  <div class="block">
 
 </div> <div class="block">
 
 </div>
 <div class="section-2">
 <div class="block-2 ">
   
 </div>
 <div class="block-2">
   
 </div><div class="block-2">
   
 </div>
 </div>
</section>
manish kumar
  • 4,412
  • 4
  • 34
  • 51
1

I agree with kidconcept that the flexbox flex-grow property is your best solution. This article is a good resource for getting started with flexbox. Some developers still shy away from the flexbox module, but it’s extremely useful and browser support is great. That said, in the spirit of trying to help you learn a bit more, I created something close to what you’re asking for using simple floats.

Fiddle

<section class="row">
  <div class="left">
      <p>Left</p>
  </div>
  <div class="right-block">
    <div class="center">
      <p>Center</p>
    </div>
    <div class="right">
      <p>Right</p>
    </div>
  <div>
  </section>

<section class="row">
  <div class="left">
      <p>Left</p>
  </div>
  <div class="right-block">
    <div class="center">
      <p>Center</p>
    </div>
    <div class="right">
      <p>Right</p>
    </div>
  <div>
</section>

.row {
  width: 100%;
  height: 180px;
  margin-top: 20px;
}
.left p, .right p {
  padding: 0 30px;
}
.left {
  height: 100%;
  background: red;
  width: 40%;
  float: left;
}
.center {
  width: 140px;
  height: 120px;
  margin: 0 20px;
  background: #4FBA49;
  float: left;
  text-align: center;
}
.right-block {
  height: 100%;
  margin-left: 20px;
  overflow: hidden;
}
.right {
  height: 100%;
  background: #FDCF1A;
  overflow: hidden;
  text-align: right;
}

On a more conceptual level, floats pull elements from the normal flow of things on the webpage, shifting them to the left or right and allowing text etc. to wrap around them. Honestly, they’re not all they’e cracked up to be imo and I’ve always found them an imperfect solution. This article gives a helpful overview of floats.

You may also find this answer helpful in understanding how to use floats together with overflow: hidden property, a useful concept that I used in my Fiddle. Finally, you'll probably also benefit from reading up on css grids as well, especially in the context of Bootstrap or some other framework. Hope this helps!

Community
  • 1
  • 1
Rich
  • 3,156
  • 3
  • 19
  • 29
  • thank you for your answer and useful links. I like your answer as well, but it also suffers from the same issue mine had, namely when the window is small, you the text overflows. – SumNeuron Feb 11 '17 at 06:39