adding border to flex items in a row aligned to baseline - html

Question: How can I get a border to stretch to the height of the parent and surround child cell. Given I am using flexbox and aligning to baseline.
Can this be done with all css?
More Details:
I am using flex box to align my items in each row to a certain baseline. It is centered on each cell under "center here" in the following picture:
When I hover currently on each item it hovers with a solid line with a 10px margin around each cell:
I want the on hover border to stretch to the top and bottom of the row on hover like this:
That way when I hover on each item, their hover border boxes would line up like this:
^ this is what I would like it to look like if I turn hover on, on each cell.
codepen
/* on hover i want this to be a box around the item, and to have the top and the bottom of the border be touching the top/bottom of the row it is on */
.flex-item:hover {
border: 1px solid darkred;
}
/* so item doesn't move when not hovering */
.flex-item {
border: 1px solid lightblue;
}
.flex-container {
overflow: hidden; position: relative;
display: -webkit-flex;
display: flex;
-webkit-align-items: baseline;
align-items: baseline;
width: 400px;
height: 350px;
background-color: lightblue;
flex-wrap: wrap;
padding: 10px;
}
.inner-wrapper {
display: inline-block;
text-align: center;
width: 100px;
margin: 10px;
background-color: cornflowerblue;
}
.flex-body {
border-bottom: 1px solid #fff;
}
.flex-body-more {
float: left;
clear: left;
width: 100%;
}
.flex-img {
justify-content: center;
align-items: center;
}
<div class="flex-container">
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/90x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1 longer title</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x90/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text more text more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/90x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x50/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
</div>

Just a few rules that you'll need to adjust to your flex items:
.flex-item {
border: 1px solid lightblue;
transition: .7s;
display: flex;
align-items: flex-end;
}
.flex-container {
overflow: hidden;
position: relative;
display: -webkit-flex;
display: flex;
width: 400px;
height: 350px;
background-color: lightblue;
flex-wrap: wrap;
padding: 10px;
justify-content: flex-start;
}
See code snippet below:
/* on hover i want this to be a box around the item, and to have the top and the bottom of the border be touching the top/bottom of the row it is on */
.flex-item:hover {
border: 1px solid darkred;
}
/* so item doesn't move when not hovering */
.flex-item {
border: 1px solid lightblue;
transition: .7s;
display: flex;
align-items: flex-end;
}
.flex-container {
overflow: hidden;
position: relative;
display: -webkit-flex;
display: flex;
width: 400px;
height: 350px;
background-color: lightblue;
flex-wrap: wrap;
padding: 10px;
justify-content: flex-start;
}
.inner-wrapper {
display: inline-block;
text-align: center;
width: 100px;
margin: 10px;
background-color: cornflowerblue;
}
.flex-body {
border-bottom: 1px solid #fff;
}
.flex-body-more {
float: left;
clear: left;
width: 100%;
}
.flex-img {
justify-content: center;
align-items: center;
}
<div class="flex-container">
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/90x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1 longer title</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x90/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text more text more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/90x40/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
<div class="flex-item">
<div class="inner-wrapper">
<div class="flex-title">flex title1</div>
<div class="flex-img">
<img src='http://dummyimage.com/40x50/000/ffffff&text=hi'>
</div>
<div class="flex-body">center here</div>
<div class="flex-body-more">more text</div>
</div>
</div>
</div>

Related

How to align cards horizontally with an equal top border, with CSS?

How to align display: inline-block cards horizontally with an equal top border, with CSS?
Why is there a unequal top boder for each card when you open the following snippet in Full page width?
I used a fixed height and width for each .card element so I expected that it would be aligned.
Note: I also tried with display: table-cell but then I lost the fact that it's fluid and that the cards auto-adapt to the browser width (I'd like to keep an automatic number of cards per row, fitting the browser width, without having a horizontal scrollbar).
#main { width: 100%; }
.cell { display: inline-block; }
.card { border: 1px solid black; margin: 3em; width: 15em; height: 30em; }
.card img { width: 15em; height: 20em; }
.container { padding: 2px 16px; height: 10em; width: 100%; box-sizing: border-box; }
<div id="main">
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla blablabla</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla blablabla blablabla blablabla blablabla blablabla blablabla blablabla blablabla blablabla</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla blablabla</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla</p>
</div>
</div>
</div>
</div>
#main { width: 100%; display: grid; grid-template-columns: repeat(auto-fill, 320px); justify-content: center; }
.card { border: 1px solid black; margin: 3em; width: 15em; height: 30em; }
.card img { width: 15em; height: 20em; }
.container { padding: 2px 16px; height: 10em; width: 100%; box-sizing: border-box; }
<div id="main">
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla blablabla</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla blablabla blablabla blablabla blablabla blablabla blablabla blablabla blablabla blablabla</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla blablabla</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla</p>
</div>
</div>
</div>
</div>
do you mean something around these lines ?
#main {
display: flex;
gap: 40px;
flex-wrap: wrap;
width: 100%;
}
.cell { display: inline-block; }
.card { border: 1px solid black; width: 15em; height: 30em; }
.card img { width: 15em; height: 20em; }
.container { padding: 2px 16px; height: 10em; width: 100%; box-sizing: border-box; }
<div id="main">
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla blablabla</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla blablabla blablabla blablabla blablabla blablabla blablabla blablabla blablabla blablabla</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla blablabla</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="">
<div class="container">
<h4><b>Abc</b></h4>
<p>blablabla</p>
</div>
</div>
</div>
</div>
You could add vertical-align: middle to your cell class.
.cell { display: inline-block; vertical-align: middle;}
Super easy with flex and grid altogether. Flex is good for self center and adjustment. Grid will help us for the whole page margins and alignment:
.container {
display: grid;
align-items: center;
justify-content: center;
height: 100%;
}
.card {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 200px;
height: 200px;
background-color: lightblue;
padding: 20px;
text-align: center;
}
You can adjust the width and height of the card to fit your needs, and also modify the padding and text alignment as desired.
P.S: Also, if you demand scrollbars to work, don't use flexbox. Change it to grid:
.card {
display: flex;
}
Here is the coding block. Will be my first time so behold:)
.container {
display: grid;
align-items: center;
justify-content: center;
height: 100%;
}
.card {
display: grid;
flex-direction: column;
align-items: center;
justify-content: center;
width: 200px;
height: 200px;
background-color: lightblue;
padding: 20px;
text-align: center;
}
.topnav {
white-space: nowrap;
display: grid;
grid-auto-flow: column;
overflow-x: scroll;
width: 20rem;
}
.topnav a,
.topnav button {
float: left;
display: block;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
<div class="container">
<div class="twitter-card">
<p>Here is the card</p>
<textarea cols="40" rows="10" ></textarea>
<div class="topnav">
<button>BIST </button>
<button>BIST Fav</button>
<button>EMTIA </button>
<button>Other</button>
<button>Other</button>
<button>Other </button>
<button>Other </button>
</div>
</div>
</div>

how to center the first item in a flexbox slider/carousel

I want to build a simple scroll slider with flexbox with three items. I want the first item to be centered in the page (under the headline) but the following items only should have a less margin.
HTML:
<div class="page-width">
<h1>Headline</h1>
<div class="container">
<div class="flex-item">
<div class="flex-wrapper">
Center me
</div>
</div>
<div class="flex-item">
<div class="flex-wrapper">
Hello World
</div>
</div>
<div class="flex-item">
<div class="flex-wrapper">
Hello World
</div>
</div>
</div>
</div>
CSS:
.page-width {
max-width: 500px;
border: 5px solid green;
}
h1 {
text-align: center;
}
.container {
display: flex;
justify-content: flex-start;
overflow: scroll;
}
.flex-item {
margin-left: 20px;
}
.flex-wrapper {
background: blue;
width: 250px;
height: 250px;
}
How can I achieve to center the first item, while the second and third only remain with a margin of 20px? Also, it should be responsive, for example when the page width is smaller, the first item should still be centered.
I tried to use
.flex-item {
flex: 0 0 100%
}
and center the wrapper inside, so the box would be in the center, but then the second and third item are outside of the screen.
Codepen: https://codepen.io/ascena/pen/wvqZgzg
.page-width {
max-width: 500px;
border: 5px solid green;
}
h1 {
text-align: center;
}
.container {
display: flex;
justify-content: flex-start;
overflow: scroll;
padding-left:20%;
}
.flex-item {
margin-left: 20px;
}
.flex-wrapper {
background: blue;
width: 250px;
height: 250px;
}
<div class="page-width">
<h1>Headline</h1>
<div class="container">
<div class="flex-item">
<div class="flex-wrapper">
Center me
</div>
</div>
<div class="flex-item">
<div class="flex-wrapper">
Hello World
</div>
</div>
<div class="flex-item">
<div class="flex-wrapper">
Hello World
</div>
</div>
</div>
</div>

CSS: What are the behavior rules for a "width: auto" container with inline-flex?

I was trying to create a list / table view with dynamic width using flexbox, and encountered a behavior I couldn't really wrap my head around. The result I'm trying to achieve is a width that fits the content of the list, at its' widest point.
.main {
width: auto;
background: rgb(233, 148, 148);
display: inline-flex;
flex-wrap: wrap;
}
.container {
display: flex;
width: 100%;
}
.label,
.value {
flex: 1;
padding: 4px;
}
.label {
text-align: end;
border-right: 2px solid red;
}
.value {
text-align: start;
}
<div>
<div class="main">
<div class="container">
<div class="label">Some Label</div>
<div class="value">Some value</div>
</div>
<div class="container">
<div class="label">Some label 2</div>
<div class="value">Other val</div>
</div>
<div class="container">
<div class="label">Third label</div>
<div class="value">
<div>N/A</div>
</div>
</div>
</div>
</div>
What it boils down to, is that the width seems to be determined by the total characters count, and not the widest point, as I would expect. You can edit the HTML and remove the N/A, for example, and the width will decrease.
When I switch to display: inline-block with white-space: nowrap, the width is as expected, but the "columns" are not aligned.
.main {
width: auto;
background: rgb(233, 148, 148);
display: inline-block;
white-space: nowrap;
}
.container {
display: flex;
width: 100%;
}
.label,
.value {
flex: 1;
padding: 4px;
}
.label {
text-align: end;
border-right: 2px solid red;
}
.value {
text-align: start;
}
<div>
<div class="main">
<div class="container">
<div class="label">Some Label</div>
<div class="value">Some value</div>
</div>
<div class="container">
<div class="label">Some label 2</div>
<div class="value">Other val</div>
</div>
<div class="container">
<div class="label">Third label</div>
<div class="value">
<div>N/A</div>
</div>
</div>
</div>
</div>
What causes the large width to occur when the display is inline-flex? Is there a way to get the behavior I'm trying to achieve? I know it can probably be resolved with display: grid, but I'm looking for a simpler solution.
I know it can probably be resolved with display: grid, but I'm looking for a simpler solution.
It might be difficult if you do not handle the grid-layout fine enough yet, but it looks not that much complicated if you use the grid system ;)
For the width, look at max-content.
simple example:
.main {
width: max-content;
background: rgb(233, 148, 148);
}
.container {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.label,
.value {
padding: 4px;
}
.label {
text-align: end;
border-right: 2px solid red;
}
.value {
text-align: start;
}
<div>
<div class="main">
<div class="container">
<div class="label">Some Label</div>
<div class="value">Some value</div>
</div>
<div class="container">
<div class="label">Some label 2</div>
<div class="value">Other val</div>
</div>
<div class="container">
<div class="label">Third label</div>
<div class="value">
<div>N/A</div>
</div>
</div>
</div>
</div>
In the past ,before flex & grid , display would use the table-layout.
.main {
display:table;
background: rgb(233, 148, 148);
}
.container {
display: table-row;
}
.label, .value {
padding: 4px;
display:table-cell;
}
.label {
text-align: end;
border-right: 2px solid red;
}
.value {
text-align: start;
}
<div>
<div class="main">
<div class="container">
<div class="label">Some Label</div>
<div class="value">Some value</div>
</div>
<div class="container">
<div class="label">Some label 2</div>
<div class="value">Other val</div>
</div>
<div class="container">
<div class="label">Third label</div>
<div class="value">
<div>N/A</div>
</div>
</div>
</div>
</div>

How to get nested css flex to have the right width after wrap in this setup?

I have this mockup, there are some nested containers. some of the link-class have multiple elements (par and ref) and I want them to display next to each other if there's space, but responsively move them below each other when total width gets smaller.
It works somewhat, but I expect (want) the link-element containing two childs to return to the same width as the link-element with one single child as it wraps.
For some reason, it remains wider than the single-child ones.
Any hints appreciated!
Code:
let name = 'world';
:global(body) {
margin: 0;
padding: 0
}
.main {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
background-color: gray;
}
.Container {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: lightblue;
padding: 3px
}
.linkContainer {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 3px;
background-color: salmon;
}
.par {
width: 80vw;
max-width: 300px;
background-color: red
}
.links {
display: flex;
flex-flow: row wrap;
padding: 3px;
background-color: orange
}
.ref {
background-color: olive;
width: 30vw;
max-width: 100px
}
.item {
width: 80vw;
max-width: 300px;
background-color: steelblue
}
<div class="main">
<div class="Container">
<div class="item">
header
</div>
<div class="linkContainer">
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="Container">
<div class="item">
another header
</div>
<div class="linkContainer">
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
</div>
</div>
</div>
</div>
</div>
you could simply add a max-width:300px; to .links and have the box in size but then you couldn't have the desired stacking effect you wanted so i went a bit further and with the help of css variables and media queries and adding a class .single to single .pars which didn't have a .ref after them, i came up with this:
:root {
--ref-size: 100px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
background-color: gray;
}
.Container {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: lightblue;
padding: 3px
}
.links {
min-width: 300px;
display: flex;
flex-flow: row wrap;
padding: 3px;
background-color: orange;
}
.par {
width: calc(100% - var(--ref-size));
background-color: red;
}
.ref {
background-color: olive;
width: var(--ref-size);
}
.item {
width: 80vw;
max-width: 300px;
background-color: steelblue
}
#media all and (max-width:300px){
.par{
width: 100%;
}
}
#media all and (min-width: 300px){
.par.single{
width: 100%;
}
}
<div class="main">
<div class="Container">
<div class="item links">
header
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="item links">
another header
</div>
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
<div class="links">
<div class="par single">
some text
</div>
</div>
<div class="links">
<div class="par">
some text
</div>
<div class="ref">
a ref
</div>
</div>
</div>
</div>

Flexbox items of same size

How can I force flexbox items to have same height.
In examples I found online, people are using align-items: stretch css property, but my example is more complex.
Here is a codepen example:
.container {
background-color: red;
display: flex;
align-items: stretch;
}
.boxes {
background-color: yellow;
margin: 5px;
display: flex;
}
.boxes-column {
flex-direction: column;
}
.box {
background-color: green;
width: 100px;
margin: 5px;
}
.heading {
background-color: pink;
}
<body>
<div class="container">
<div class="boxes boxes-column">
<div class="heading">This is heading</div>
<div class="boxes">
<div class="box">Content content content content content content content</div>
<div class="box">Content content</div>
<div class="box">Content</div>
<div class="box">Contento contento</div>
<div class="box">Cc</div>
<div class="box">Contetno contento contento</div>
</div>
</div>
<div class="boxes boxes-column">
<div class="heading">This is heading 2</div>
<div class="boxes">
<div class="box">Content</div>
<div class="box">Contentno Contetn</div>
<div class="box">C</div>
</div>
</div>
</div>
</body>
Height of items items below 'Heading' and height of items below 'Heading 2' should be equal.
Used this css and now the boxes have the same height:
.container > .boxes > .boxes {
flex: 1;
}
Take a look at the below snippet:
.container {
background-color: red;
display: flex;
align-items: stretch;
}
.boxes {
background-color: yellow;
margin: 5px;
display: flex;
}
.boxes-column {
flex-direction: column;
}
.box {
background-color: green;
width: 100px;
margin: 5px;
}
.heading {
background-color: pink;
}
.container > .boxes > .boxes {
flex: 1;
}
<body>
<div class="container">
<div class="boxes boxes-column">
<div class="heading">This is heading</div>
<div class="boxes">
<div class="box">Content content content content content content content</div>
<div class="box">Content content</div>
<div class="box">Content</div>
<div class="box">Contento contento</div>
<div class="box">Cc</div>
<div class="box">Contetno contento contento</div>
</div>
</div>
<div class="boxes boxes-column">
<div class="heading">This is heading 2</div>
<div class="boxes">
<div class="box">Content</div>
<div class="box">Contentno Contetn</div>
<div class="box">C</div>
</div>
</div>
</div>
</body>