CSS/ Flexbox: Same width as largest element, like columns - css

I've built a list component for my app, I can't use tables because of the style.
I want to have the elements inside of the "rows" to have the same width from top to bottom, like columns. The code looks similar to this:
<div class="row">
<div class"element>iPhone </div>
<div class"element>Buy an iPhone now!</div>
</div>
<div class="row">
<div class"element>Airport Express </div>
<div class"element>Buy an Airport Express now!</div>
</div>
<div class="row">
<div class"element>iPad </div>
<div class"element>Buy an iPad now!</div>
</div>
This is what it currently looks like:
And this is, what I want:
Is there a way to do this?

Use CSS tables:
Separation between rows with border-spacing
Borders in cells. You can use border-radius to round them.
Pseudo-element displayed as cell to fill available space at the right
white-space: nowrap to prevent cells from shrinking due to the pseudo-element.
.wrapper {
display: table;
border-spacing: 0 10px;
}
.row {
display: table-row;
border: 1px solid;
}
.row::after {
content: '';
display: table-cell;
width: 100%;
border: 1px #6AACC9;
border-style: solid none;
}
.element {
display: table-cell;
border: 1px solid #6AACC9;
border-right-color: #adadad;
border-left-style: none;
padding: 5px;
white-space: nowrap;
}
.element:first-child {
border-left-style: solid;
border-radius: 5px 0 0 5px;
}
<div class="wrapper">
<div class="row">
<div class="element">iPhone </div>
<div class="element">Buy an iPhone now!</div>
</div>
<div class="row">
<div class="element">Airport Express </div>
<div class="element">Buy an Airport Express now!</div>
</div>
<div class="row">
<div class="element">iPad </div>
<div class="element">Buy an iPad now!</div>
</div>
</div>

You can't do that with flexbox. Dimensions cannot be equallised between elements that do not share a parent.
But you can with CSS Tables
.row {
display: table-row;
}
.element {
display: table-cell;
border: 1px solid grey;
padding: 8px;
}
<div class="row">
<div class="element">iPhone</div>
<div class="element">Buy an iPhone now!</div>
</div>
<div class="row">
<div class="element">Airport Express</div>
<div class="element">Buy an Airport Express now!</div>
</div>
<div class="row">
<div class="element">iPad</div>
<div class="element">Buy an iPad now!</div>
</div>

Related

The rounded corners of the images inside a card don't look right

I have multiple cards with images inside those cards. I want the images to have rounded corners. The code kind of worked but the rounded corners don't look right.
For the images, I'm just using the Bootstrap class rounded. The images are scaled down but not distorted. This is the CSS for the cards:
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #F5F5F5;
background-clip: border-box;
border: 0.0625rem solid #E5E7EB;
border-radius: 1rem; }
Simplified HTML:
<div class="card border-0 p-3 p-md-3 p-lg-4 mb-3">
<div class="row pb-4 text-left">
<div class="col-1 ps-1">
<h1 class="id-circle">B</h1>
</div>
<div class="col-11">
<span class="description details-text pe-1">Text</span>
</div>
</div>
<div class="row gy-3 mb-1 pb-0">
<div class="col-lg-6 col-md-6 col-sm-6 pb-0">
<div class="row pt-0 pb-0 image-row">
<img class="rounded" src="https://picsum.photos/id/237/300/200">
</div>
</div>
</div>
</div>
Any ideas of what could be happening? Please let me know if more info is needed.
Check below snippet: with your CSS and HTML, in both cases the bootstrap creates a small rounded corner of 4px around the images using .rounded { border-radius: .25rem !important } (Firefox DevTools). In fact, with your HTML (second card), the rounded borders of the image are gone.
Still not showing the unwanted result you are experiencing. Something else in your CSS creates the result.
The odd border radius in the image is not reproducable on Stackoverflow with your code.
I added below CSS to override bootstrap .rounded in my Codepen test and got the same unwanted result. You must have done something similar. However, I still don't see it happening here on SO.
My Codepen: SO74554098
.rounded {
border-radius: 1rem !important;
}
The best option would, indeed, be to create a specific card layout for the images (as OP commented, 'card in a card') and use bootstrap .rounded or a custom class with border-radius set.
.card {
/* added for test */
padding: 1rem; margin: 1rem; outline: 1px solid black;
/**/
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #f5f5f5;
background-clip: border-box;
border: 0.0625rem solid #e5e7eb;
border-radius: 1rem;
}
.rounded {
border-radius: 1rem !important;
}
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<h3>only .card > .rounded</h3>
<div class="card">
<img class="rounded" src="https://picsum.photos/id/237/300/200">
</div>
<h3>OP code with full bootstrap CSS (5.0.2)</h3>
<div class="card border-0 p-3 p-md-3 p-lg-4 mb-3">
<div class="row pb-4 text-left">
<div class="col-1 ps-1">
<h1 class="id-circle">B</h1>
</div>
<div class="col-11">
<span class="description details-text pe-1">Text</span>
</div>
</div>
<div class="row gy-3 mb-1 pb-0">
<div class="col-lg-6 col-md-6 col-sm-6 pb-0">
<div class="row pt-0 pb-0 image-row">
<img class="rounded" src="https://picsum.photos/id/237/300/200">
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/js/bootstrap.min.js"></script>
</body>
</html>
Try doing
border-radius: 25px;
sometimes rem doesn't work for border radius

CSS question: Flexible width to make it reflow ready

Could anyone please help me with this, How can I make the parent container flexible and make it reflow ready?
.container{
width: 350px;
border: 1px solid red;
}
.item{
margin-top:2px;
display: flex;
}
.line{
flex-grow:1;
}
<div class="container">
<div class="item">
<div class="line"><span>xyx</span></div>
<span>10 USD</span>
</div>
<div class="item">
<div class="line"><span>q</span></div>
<span>* 2</span>
</div>
<div class="item">
<div class="line"><span>total</span></div>
<span>20 USD</span>
</div>
</div>
Since you are referring reflow as browser width change and your default width for the container is 350px
just your change width: 350px to max-width: 350px. Your container is now responsive for smaller browser width
You can play around around here and change the browser here:
.container{
max-width: 350px;
border: 1px solid red;
}
.item{
margin-top:2px;
display: flex;
}
.line{
flex-grow:1;
}
<div class="container">
<div class="item">
<div class="line"><span>xyx</span></div>
<span>10 USD</span>
</div>
<div class="item">
<div class="line"><span>q</span></div>
<span>* 2</span>
</div>
<div class="item">
<div class="line"><span>total</span></div>
<span>20 USD</span>
</div>
</div>

Sticky left cell in flexbox table on 'category' change

I have a list of items that I am presenting in a flexbox table. My actual display has more columns, but in this question, I'll use just 2 - the 'category' and 'item' names. The data is presented in category order. Where items repeat for a category, only the first item for the category should have the category listed, for subsequent ones I want the category cell empty. As this can scroll off the top of the screen, I'd like to make this cell sticky, as I do for the headings.
However, as the cell is a child of the row, not the container of the table, it scrolls up with the row. You can see this in the first table in the example below, the '.first_item' CSS class does not hold the caption in place.
I concluded that the only way to achieve this is to insert a div before the row to present the category and make this sticky - class cat_head in the 2nd table in the example below. This works, however, it knocks the first item down and does not align where I want it to. I therefore set its height to 0px, which brings the item row back into alignment, but then have to put the text within an absolute positioned div within this so that I can set a background colour to stop text for the categories from overlaying each other.
It works really well and is exactly how I'd like it to operate - except that because the height is set to 0px, the absolute div extends below the bottom of the table as it is scrolled off the top of the screen and overwrites what is below it - you can see in the example it overwrites "Text below".
I also have to manually add an 'alt' class name on alternate rows to get background colouring rather than relying on ':nth-child(even)' - but I can live with this.
Has anyone got any suggestions for stopping it falling out of the bottom of the container, or indeed a better way of doing this? Thanks.
.pad {
height: 50px;
background-color: yellow;
}
.fill {
height: 120vh;
background-color: yellow;
}
.container {
background-color:#ffffff;
}
.row {
display: flex;
flex-flow:row wrap;
}
.head {
position: sticky;
top: 0px;
background-color: #e0e0e0;
font-weight: bold;
border-bottom: 1px solid #000000;
height: 24px;
z-index: 3;
}
.cell {
flex: 0 0 100px;
padding: 5px;
}
.first_item {
position: sticky;
top: 25px;
z-index: 2;
}
.table_1 .row:nth-child(even),
.table_2 .alt {
background-color: #f0f0f0;
}
.cat_head {
position: sticky;
top: 25px;
height:0px;
overflow: visible;
z-index: 2;
}
.cat_text {
position: absolute;
width: 80px;
padding: 0;
background-color: rgba(8,156,213,1);
color: #ffffff;
border: 1px solid #000000;
border-radius:5px;
margin:2px 0 0 4px;
text-align:center;
}
<div class="pad"></div>
<div class="container table_1">
<div class="row head">
<div class="cell">Category</div>
<div class="cell">Item</div>
</div>
<div class="row cat">
<div class="cell first_item">Category 1</div>
<div class="cell">Item 1-1</div>
</div>
<div class="row">
<div class="cell"></div>
<div class="cell">Item 1-2</div>
</div>
<div class="row">
<div class="cell"></div>
<div class="cell">Item 1-3</div>
</div>
<div class="row cat">
<div class="cell first_item">Category 2</div>
<div class="cell">Item 2-1</div>
</div>
<div class="row">
<div class="cell"></div>
<div class="cell">Item 2-2</div>
</div>
</div>
<div class="pad">Text below</div>
<div class="container table_2">
<div class="row head">
<div class="cell">Category</div>
<div class="cell">Item</div>
</div>
<div class="cat_head">
<div class="cat_text">Category 1</div>
</div>
<div class="row alt">
<div class="cell"></div>
<div class="cell">Item 1-1</div>
</div>
<div class="row">
<div class="cell"></div>
<div class="cell">Item 1-2</div>
</div>
<div class="row alt">
<div class="cell"></div>
<div class="cell">Item 1-3</div>
</div>
<div class="cat_head">
<div class="cat_text">Category 2</div>
</div>
<div class="row">
<div class="cell"></div>
<div class="cell">Item 2-1</div>
</div>
<div class="row alt">
<div class="cell"></div>
<div class="cell">Item 2-2</div>
</div>
</div>
<div class="fill">Text below</div>
OK. So I went to sleep on it and realised that the sticky positioning when scrolling off the top of the viewport is based on the bottom of its div. Therefore, I need to shift the div below the row it is on - as its 0px high and that's where its 'bottom' should be.
I also need to move the contained absolute div above it rather than below so its bottom aligns to it. I initially put a -24px top margin on the absolute div, but this stopped the sticky positioning on its parent for some reason. I therefore put a -24px top margin on the sticky div, which worked. However, it also dragged the next row up, so I also added a 24px bottom margin which resolved that.
I also added a containing div around each category's rows so that the sticky heading scrolls off screen when the next category gets to the top.
All working fine.
.pad {
height: 50px;
background-color: yellow;
}
.fill {
height: 120vh;
background-color: yellow;
}
.container {
background-color:#ffffff;
}
.row {
display: flex;
flex-flow:row wrap;
}
.head {
position: sticky;
top: 0px;
background-color: #e0e0e0;
font-weight: bold;
border-bottom: 1px solid #000000;
height: 24px;
z-index: 3;
}
.cell {
flex: 0 0 100px;
padding: 5px;
}
.alt {
background-color: #f0f0f0;
}
.cat_head {
position: sticky;
top: 27px;
height:0px;
margin: -24px 0 24px 4px;
overflow: visible;
z-index: 2;
}
.cat_text {
position: absolute;
width: 80px;
padding: 0;
background-color: rgba(8,156,213,1);
color: #ffffff;
border: 1px solid #000000;
border-radius:5px;
text-align:center;
}
<div class="pad"></div>
<div class="container">
<div class="row head">
<div class="cell">Category</div>
<div class="cell">Item</div>
</div>
<div>
<div class="row alt">
<div class="cell"></div>
<div class="cell">Item 1-1</div>
</div>
<div class="cat_head">
<div class="cat_text">Category 1</div>
</div>
<div class="row">
<div class="cell"></div>
<div class="cell">Item 1-2</div>
</div>
<div class="row alt">
<div class="cell"></div>
<div class="cell">Item 1-3</div>
</div>
</div>
<div>
<div class="row">
<div class="cell"></div>
<div class="cell">Item 2-1</div>
</div>
<div class="cat_head">
<div class="cat_text">Category 2</div>
</div>
<div class="row alt">
<div class="cell"></div>
<div class="cell">Item 2-2</div>
</div>
</div>
</div>
<div class="fill">Text below</div>

Make a vertical bar reaching both the top and bottom of a page

I'm creating a vertical bar to split the sidebar and the main-section.
I employed the grid bootstrap 3:
<div class="container">
<div class="row">
<aside class="col-md-2 left-sidebar">
<ul>
<li>Javascript</li>
<li>jQuery</li>
<li>Bootstrap</li>
</ul>
</aside>
<div class="col-md-10 main-section">
....
</div>
<div>
the css code:
.left-sidebar {
padding-top: 50px;
border-right: 1px solid red;
}
I found the official docs of Bootstrap 4.1 has a nicely structured left-side.
How to produce a vertical var reaching both the top and bottom of the page?
Use the below snippet to get the equal height columns to your bootstrap grid.
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.row-eq-height > [class*='col-'] {
display: flex;
flex-direction: column;
}
.left-sidebar {
box-shadow: 1px 0 0 0 #ccc;
background: #eee;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet"/>
<div class="row row-eq-height">
<div class="col-sm-2 left-sidebar">
some content
</div>
<div class="col-sm-10" style="height: 100vh">
some more content
</div>
</div>
Boostrap4 main difference from BS3 is that it's using flexbox instead of floats. And with flexbox you can make columns inside a row have equal height. So you could make 2 columns and if the main-column will have for ex 1000px height, the left column will have that height as well.
See snippet
.row {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.main-section {
height:200vh;
background: blue;
}
.left-sidebar {
border-right: 2px solid red;
background:green;
}
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-md-2 col-sm-2 col-xs-2 left-sidebar">
<ul>
<li>Javascript</li>
<li>jQuery</li>
<li>Bootstrap</li>
</ul>
</div>
<div class="col-md-10 col-sm-10 col-xs-10 main-section">
....
</div>
</div>
</div>
IF you want to have the same effect as the one from the BS4 docs, then the left column has the height of the screen. You can do that with viewport units. And it also has position:sticky.
See below ( for some reason in the code snippet position:sticky doesn't work, check it here - > jsfiddle sticky )
.row {
display: flex;
width: 100%;
}
.main-section {
height:200vh;
background: blue;
}
.left-sidebar {
border-right: 2px solid red;
height:100vh;
position:sticky;
top:0;
background:green;
}
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-md-2 col-sm-2 col-xs-2 left-sidebar">
<ul>
<li>Javascript</li>
<li>jQuery</li>
<li>Bootstrap</li>
</ul>
</div>
<div class="col-md-10 col-sm-10 col-xs-10 main-section">
....
</div>
</div>
</div>

A table web page layout using the display property in css

So I've been using CSS table display property to get a table layout on my site. Now before you go into the using 'float' property or use the HTML table tag, I prefer the CSS table layout and find it better and my mind is made up. Here is the HTML code:
<div class="page_wrap">
<div class="header">
<div class="banner">
<h1>Heading 1</h1>
<h2>Heading 2</h2>
</div>
<div class="nav">
<ul>
<li>Home</li>
<li>Topics</li>
<li>"Closet"</li>
<li>Music</li>
<li>Resources</li>
<li>About</li>
</ul>
</div>
<div class="directory"></div>
</div>
<div class="content">
<div class="main_col">
<div class="blog">
<div class="blog_head">
<h3>What To Wear Today</h3>
</div>
<div class="blog_body">
<p></p>
</div>
<div class="blog_recent"></div>
</div>
<div class="news">
<div class="news_recent"></div>
</div>
</div>
<div class="sub_col">
<div class="daily_verse">
<h3>"What Word To Wear Today"</h3>
<p></p>
</div>
<div class="bible_topic"></div>
</div>
</div>
<div class="footer">
<div class="container"></div>
</div>
</div>
And here is the CSS:
.content
{
display: table-column-group;
margin-top: 25px;
}
.main_col
{
display: table-column;
background: red;
width: 550px;
padding: 20px 15px;
}
.sub_col
{
display: table-cell;
background: green;
width: 350px;
padding: 20px 15px;
}
.blog
{
display: table-cell;
background: black;
}
.blog h3
{
padding: 20px 0px;
width: 250px;
}
.news
{
display: table-cell;
background: gray;
}
.daily_verse
{
display: table-cell;
}
.bible_topic
{
display: table-cell;
}
</style>
The problem is when I use the table-column property in the CSS, then everything in the HTML tag under the main_col div disappears.
Use this example as your structure and go from there. Your table is crazy disorganized and I don't think you are actually wanting table-columns. Or maybe an illustration of how you'd like it to look would help and we could provide code examples?
(http://xahlee.info/js/css_table.html)

Resources