How to use a nested element as a table cell - css

Imagine the following HTML:
<div class='leaderboard'>
<div class='entry'>
<div class='contestant'>
<div class='name'>Robert</div>
<div class='country'>Ireland</div>
</div>
<div class='score'>32</div>
</div>
<div class='entry'>
<div class='contestant'>
<div class='name'>Dan</div>
<div class='country'>USA</div>
</div>
<div class='score'>81</div>
</div>
</div>
Now, we all know that we can use CSS to make this a two-column table:
.leaderboard {
display: table;
}
.entry {
display: table-row;
}
.contestant, .score {
display: table-cell;
}
This will render the contestant’s name and country within one cell, and the score in another.
What I want is to be able to have three columns, with the name, country, and score, but without changing the HTML. Is this possible?
In other words, ideally, I want to be able to tell the renderer to ignore the <div class='contestants'> entirely and pretend that name and country are children of the table row.

I want to be able to tell the renderer to ignore the <div class='contestants'> entirely and pretend that name and country are children of the table row.
This is what display:contents; will do (https://caniuse.com/#feat=css-display-contents)
causes an element's children to appear as if they were direct children of the element's parent, ignoring the element itself.
.leaderboard {
display: table;
}
.entry {
display: table-row;
}
.score,
.name,
.country{
display: table-cell;
padding:10px;
}
.contestant {
display:contents;
}
<div class='leaderboard'>
<div class='entry'>
<div class='contestant'>
<div class='name'>Robert</div>
<div class='country'>Ireland</div>
</div>
<div class='score'>32</div>
</div>
<div class='entry'>
<div class='contestant'>
<div class='name'>Dan</div>
<div class='country'>USA</div>
</div>
<div class='score'>81</div>
</div>
</div>

Related

reposition different divs differently

I want to stack div differently for small screens and I want to use css for it.
What I want to achieve is following:
for one page, the div class="three has to go UNDER the .header
for another page (uses the same code), the div class="two" has to go ABOVE the .header
I only managed to make .two go above .header, but the result is that I cannot make the .three go below the .header on my other page (the actual result is that the .three is also placed ABOVE the .header because of my css code). How to fix?
#media(max-width: 460px) {
.container {
display: flex;
flex-direction: column;
}
.header {
order: 2;
}
}
<div class="body">
<div class='container'>
<div class='header'>
<div class="one">
one
</div>
hello
</div>
<div class='sidebar'>
<div class="two">
two
</div>
<div class="three">
three
</div>
</div>
</div>
</div>
Your two and three are within in a div called sidebar. You can't remove them from this div and order them with header using CSS because header is not the same level as them. You should possibly consider re-structuring your HTML?
I have amended your example slightly to show you what I mean.
.container {
display: flex;
flex-direction: column;
}
.header {
order: 2;
}
.two {
order: 1;
}
.three {
order: 3;
}
<div class="body">
<div class='container'>
<div class='header'>
<div class="one">
one
</div>
hello
</div>
<div class="two">
two
</div>
<div class="three">
three
</div>
</div>
</div>
What you want is tricky because your HTML is grouping items two and three.
The very best solution is to rearrange your HTML.
Just in case that it is not possible, you can set a workaround with display: contents on the sidebar element (this makes the element disappear from the flow)
#media(max-width: 4600px) {
.container {
display: flex;
flex-direction: column;
background-color: lightblue;
}
.header {
order: 2;
}
.three {
order: 3;
}
.sidebar {
display: contents;
}
}
<div class="body">
<div class='container'>
<div class='header'>
<div class="one">
one
</div>
hello
</div>
<div class='sidebar'>
<div class="two">
two
</div>
<div class="three">
three
</div>
</div>
</div>
</div>

How can I separate areas with floats from each other?

I'm struggling with Bootstrap rows and columns in a SharePoint web site. The problem is that I can't and don't want to change the styling that originates from SharePoint, but still be able to use the Bootstrap grid in a part of the page.
I've tried to illustrate the problem without Bootstrap and SharePoint. Here's the JSFiddle:
https://jsfiddle.net/knLjyhe4/
Below is a complete illustration of my example. The problem is that once I use a row to separate element B from C, D and E, the height of side element A affects the first row's height, which I don't want. I want element C to appear immediately below element B. The second example is how it looks before I add the div.row elements.
Below is the HTML and CSS for the isolated example. I had hoped that I could style the div.main element somehow so that the float of A doesn't affect the float of B-E at all. But I can't figure it out.
Please note that I'm sure there are several solutions if I start to change the HTML and styles (like using position), but I really just want to know if there is a way in CSS where the div.main element gets "its own" floating area, without being affected by the A element's float.
<style>
section {
width: 600px;
margin: auto;
}
.block {
float: left;
margin: 10px;
background-color: #339;
color: #fff;
width: 140px;
padding: 10px;
}
.side {
width: 200px;
height: 100px;
}
.main {
margin-left: 240px;
}
.row:after {
display: table;
content: ' ';
clear: both;
}
</style>
<section>
<div class="side block">This is element A in problematic example. I want element C immediately below element B, regardless of the height of this element</div>
<div class="main">
<div class="row">
<div class="block">This is element B</div>
</div>
<div class="row">
<div class="block">This is element C</div>
<div class="block">This is element D</div>
<div class="block">This is element E</div>
</div>
</div>
</section>
<section>
<div class="side block">This is element A when it works but without rows</div>
<div class="main">
<div class="block">This is element B</div>
<div class="block">This is element C</div>
<div class="block">This is element D</div>
<div class="block">This is element E</div>
<div class="block">This is element F</div>
<div class="block">This is element G</div>
<div class="block">This is element H</div>
<div class="block">This is element I</div>
</div>
</section>
Seems to be working if you change your CSS for .main to this (display: table-row;):
.main {
margin-left: 240px;
display: table-row;
}
Updated JSFiddle here
UPDATE 1
Changed table to table-row since it did not work in IE10.
UPDATE 2
For future reference, the final solution used in SharePoint / O365 looked something like this:
HTML (.container is a bootstrap container)
<div id="DeltaPlaceHolderMain">
<div class="container">
<div class="inner-container">
<!--Your content here-->
</div>
</div>
</div>
CSS
.container .inner-container {
display: inline-block;
width: 100%;
}
The .main needs to be float:left and it needs to have less px to width.
Try defines
.side {width:30%; float:left;}
.main{width:70%; float:left; margin-left:0; }
Don't forget to clean the margin-left of .main
The clear: both property on the row:after pseudoclass is causing your second row to jump down below the left-floated side element.
In bootstrap you should use classname col-md-4 on your side element, classname col-md-8 on your main element, and remove the float: left property from your side element. This will give you 2 columns, one for side which is 4 grids wide and one for main which is 8 grids wide. Your rows should function as you expect once the float is gone.
<style>
section {
width: 600px;
margin: auto;
}
.block {
background-color: #339;
color: #fff;
padding: 10px;
}
</style>
<section class="row">
<div class="block col-md-4">This is element A</div>
<div class="col-md-8">
<div class="row">
<div class="block col-md-6">This is element B</div>
</div>
<div class="row">
<div class="block col-md-6">This is element C</div>
<div class="block col-md-6">This is element D</div>
<div class="block col-md-6">This is element E</div>
</div>
</div>
</section>
In general, with bootstrap you don't want to float things. Also, instead of setting element widths explicitly, it is better to use the .col- classes to fit them into the bootstrap grid system.

eliminate container div element using only css

I have this structure:
<div clas="page_cat_list">
<div class="page_cat_row">
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="clear_fix"></div>
</div>
<div class="page_cat_row">
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="clear_fix"></div>
</div>
</div>
this displays 3 items in a row, but I need the page_cat_list 100% width, and as many items they fit in the row dinamically.
I used:
.clear_fix {
display: none;
}
that`s ok, and
.page_cat_row{
display: inline;
}
this way I have as many items as they fit in the row, but they are aligned left, I tried:
.page_cat_row, page_cat_list {
text-align: center;
}
but is not working
the best solution should be to eliminate the .page_cat_row element, from CSS if possibile, because I have no access to html.
It is supposed to behave like this:
<div clas="page_cat_list">
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
<div class="page_cat_item">...</div>
</div>
.page_cat_item is a div and by default 100% width so you need to center align content inside this div not the whole this
.page_cat_item {
text-align: center;
}
Also the css you were using is having an error
.page_cat_row, page_cat_list {
text-align: center;
}
In your above css you need to define . for both classes not just for first
This is correct
.page_cat_row, page_cat_list {
text-align: center;
}

Bootstrap align Columns of different height

I would like to be able to align an unknown number of columns with an unknown height. Since I do not know how many columns there will be it is not ideal for me to use multiple rows to split up the columns. I can almost achieve the outcome I want by using list items.
The one thing I don't like about using list items is that once the page hits the resize point I am left with the extra space on the right hand side. The top set is using list items and the bottom set is using bootstrap's col's. The problem with the bottom set is when the col's break they don't align to the furthest left position.
Is there a way to achieve this using bootstrap?
<div class="container-fluid">
<div class="row">
<ul>
<li class="list-item" style="height:200px;"></li>
<li class="list-item" style="height:120px;"></li>
<li class="list-item" style="height:100px;"></li>
</ul>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-3">
<div class="box" style="height:200px"></div>
</div>
<div class="col-xs-12 col-sm-6 col-md-3">
<div class="box" style="height:120px"></div>
</div>
<div class="col-xs-12 col-sm-6 col-md-3">
<div class="box" style="height:100px"></div>
</div>
<div class="col-xs-12 col-sm-6 col-md-3">
<div class="box"></div>
</div>
</div>
</div>
jsFiddle
Try this :
.row {
display: flex;
flex-wrap: wrap;
}
Another way to handle it, and still maintain Bootstrap's responsive columns is to use CSS to force a clear:left every x columns. For example, when you have 4 columns in a row:
.row > .col-md-3:nth-child(4n+1) {
clear: left;
}
http://codeply.com/go/OHg5vB0Xg3
You really don't need bootstrap to handle this. Here's one potential solution using inline-block. I imagine it's compatible with bootstrap.
.box {
margin: 15px;
width: 80px;
background-color: grey;
display: inline-block;
vertical-align: top;
}
<div>
<div class="box" style="height: 120px;"></div>
<div class="box" style="height: 20px;"></div>
<div class="box" style="height: 40px;"></div>
<div class="box" style="height: 60px;"></div>
<div class="box" style="height: 80px;"></div>
</div>
<div>
<div class="box" style="height: 20px;"></div>
<div class="box" style="height: 60px;"></div>
<div class="box" style="height: 80px;"></div>
</div>
Yes! There is a way. And it's a css-only solution. Try this:
.col-xs-6:nth-of-type(2n+3),
.col-xs-4:nth-of-type(3n+4),
.col-xs-3:nth-of-type(4n+5),
.col-xs-2:nth-of-type(6n+7),
.col-xs-1:nth-of-type(12n+13)
{
clear: both;
}
#media (min-width: 768) {
[class*="col-xs"][class*="col-sm"],
[class*="col-xs"][class*="col-md"],
[class*="col-xs"][class*="col-lg"]
{
clear: none;
}
.col-sm-6:nth-of-type(2n+3),
.col-sm-4:nth-of-type(3n+4),
.col-sm-3:nth-of-type(4n+5),
.col-sm-2:nth-of-type(6n+7),
.col-sm-1:nth-of-type(12n+13)
{
clear: both;
}
}
#media (min-width: 992) {
[class*="col-sm"][class*="col-md"],
[class*="col-sm"][class*="col-lg"]
{
clear: none;
}
.col-md-6:nth-of-type(2n+3),
.col-md-4:nth-of-type(3n+4),
.col-md-3:nth-of-type(4n+5),
.col-md-2:nth-of-type(6n+7),
.col-md-1:nth-of-type(12n+13)
{
clear: both;
}
}
#media (min-width: 1200) {
[class*="col-md"][class*="col-lg"]
{
clear: none;
}
.col-lg-6:nth-of-type(2n+3),
.col-lg-4:nth-of-type(3n+4),
.col-lg-3:nth-of-type(4n+5),
.col-lg-2:nth-of-type(6n+7),
.col-lg-1:nth-of-type(12n+13) {
clear: both;
}
}
// use .col-nobreak class to deactivate this fix
.col-nobreak {
clear: none !important;
}
First of all we begin with the column type for the smallest resolution (< 768) (col-xs-*). If the row breaks for the several column widths, we set the css property clear to clear: both.
In the next step we reset for the first breakpoint the css property clear with clear: both for all columns, which has a column width for higher resolutions (all columns width additional col-sm-x,col-md-x,col-lg-x) and set the break of one column-row for the col-sm-* type.
And so on...
With the .col-nobreak class you can deactivate the css hack.
You have to fulfill these requirements:
The cols for the parent row container must have the same size
The cols for the parent row must have the same html tag type (div, secion)

What is the proper arrangement for table-header-group?

I'm trying to build a footer that has two title columns and three content columns.
I'd like to use display: table-cell for the content columns, and believe I need to use display: table-header-group for the title columns.
While researching display: table-header-group, I could not find any documentation at all on how to use this CSS property. W3Cschools says the following.
table-header-group: Let the element behave like a thead element.
(source)
That unfortunately doesn't tell me how I should arrange my divs
So far I've got the following code, but I'm not sure if I'm using table-header-group correctly
.footer {
display: table;
}
.footer-box {
display: table-cell;
}
.footer-title-box {
display: table-header-group;
}
<div class="footer">
<div class="footer-title-box">
Title
</div>
<div class="footer-title-box">
Title
</div>
<div class="footer-box">
Content
</div>
<div class="footer-box">
Content
</div>
<div class="footer-box">
Content
</div>
</div>
If anyone has any experience with table-header-group and could shed some light on it, I would be incredibly grateful.
I don't have any experience with it but logic dictates that you can only have one thead so you can only have one table-header-group
So your structure should, perhaps, look more like this:
JSfiddle Demo Backup Link
.footer {
display: table;
width: 50%;
table-layout: fixed;
}
.footer-title-box {
display: table-header-group;
font-weight: bold;
}
.footer-row-box {
display: table-row-group;
}
.footer-box {
display: table-cell;
text-align: center;
}
<div class="footer">
<div class="footer-title-box">
<div class="footer-box">Title</div>
<div class="footer-box caption">Title</div>
</div>
<div class="footer-row-box">
<div class="footer-box">Content</div>
<div class="footer-box">Content</div>
<div class="footer-box">Content</div>
</div>
<div class="footer-row-box">
<div class="footer-box">Content</div>
<div class="footer-box">Content</div>
<div class="footer-box">Content</div>
</div>
<div class="footer-row-box">
<div class="footer-box">Content</div>
<div class="footer-box">Content</div>
<div class="footer-box">Content</div>
</div>
</div>

Resources