Home > OS >  CSS: Two column layout when only one column content has a wrapper element
CSS: Two column layout when only one column content has a wrapper element

Time:12-25

Given the following structure:

<form>
  <label for="id_foo">Foo:</label>
  <input type="text" name="foo" required="" id="id_foo">
  <label for="id_bar">Bar:</label>
  <input type="text" name="bar" required="" id="id_bar">
  <label for="id_baz">Baz:</label>
  <input type="text" name="baz" required="" id="id_baz">
  <label>Select:</label>
  <div id="id_select">
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
  </div>
  <input type="submit">
</form>

without modifying the html and assuming the number of check boxes is somewhat dynamic.

Can this be rendered sensibly in two columns:

  • input fields fill one column after another
  • with labels above each input within one row
  • height of items on one column independent of those in the other column.

target visualization

I understand this is trivial if I had a container for the tags of each column, but I want to understand if/how it is possible to achieve without.

With grid layout, I come close, but I the number of checkboxes will influence the height of the input fields / labels on the left.

With columns / column-count I can't seem to find a way to control the break.

Note: The reason I don't want to modify the html is mostly because the framework I'm using (Django) does make it rather intrusive to mess with form rendering. Moreover, this specific layout is only for certain screen sizes. I dislike tuning the html with different responsive layouting in mind. I am willing to accept some additional complexity in the CSS in this case, and want to figure out if this is feasible.

CodePudding user response:

What I’d do is put the #id_select in a absolutely positioned block on the right top, which would prevent it from affecting the height of the main content with labels inputs.

form {
  position: relative;
  padding-right: 100px;
  /* make space for the #id_select block */
}

label,
input {
  display: block;
  /* make them fill in width to go one after another vertically */
}

#id_select {
  position: absolute;
  right: 0;
  top: 0;
  width: 100px;
}
<form>
  <label for="id_foo">Foo:</label>
  <input type="text" name="foo" required="" id="id_foo">
  <label for="id_bar">Bar:</label>
  <input type="text" name="bar" required="" id="id_bar">
  <label for="id_baz">Baz:</label>
  <input type="text" name="baz" required="" id="id_baz">
  <label>Select:</label>
  <div id="id_select">
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
  </div>
  <input type="submit">
</form>

CodePudding user response:

The grid display could help you. defaut will draw a single column, unless you specify an element to stand in another column.

If you use ID , you may work something out wherever IDs are found or not.

Example with your form , with and without IDS , both are a form{display:grid;}

   /* defaut layout as a grid of one column , gap can be used */
form {
display:grid;
gap:0.5em;
padding:0.5em;
border:solid;
margin:1em;
}
/* element dispatched inside grid-column:2 , will make form draw 2 columns */
#id_select {
grid-column:2;
grid-row:2 / 6;
display:grid;
}
#label_select{grid-row:1;}
#id_select ~input[type="submit"] {
grid-row:6;
}
#label_select,
#id_select ~input[type="submit"] {
grid-column:2;
}
<h1>I'll be 2 columns !</h1>
<form>
  <label for="id_foo">Foo:</label>
  <input type="text" name="foo" required="" id="id_foo">
  <label for="id_bar">Bar:</label>
  <input type="text" name="bar" required="" id="id_bar">
  <label for="id_baz">Baz:</label>
  <input type="text" name="baz" required="" id="id_baz">
  <label id="label_select">Select:</label>
  <div id="id_select">
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
  </div>
  <input type="submit">
</form>
<h2>I'll be a single column</h2>
<form>
  <label for="id_foo">Foo:</label>
  <input type="text" name="foo" required="" id="id_foo">
  <label for="id_bar">Bar:</label>
  <input type="text" name="bar" required="" id="id_bar">
  <label for="id_baz">Baz:</label>
  <input type="text" name="baz" required="" id="id_baz">
  <label>Select:</label>
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>
    <div><input type="checkbox"><label>Test</label></div>

  <input type="submit">
</form>

  • Related