Adding a CSS Pseudo Elements to center of a grid only - css

.parnet{
max-width: 600px;
margin: 0 auto;
background: #f4f4f5;
}
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.cell {
position: relative;
}
.inner {
width: 80px;
height: 80px;
padding: 40px;
text-align: left;
}
.wrapper .cell:nth-child(2n):before{
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 60%;
width: 1px;
background-color:red;
}
<div class="parnet">
<div class="wrapper">
<div class="cell">
<div class="inner">1</div>
</div>
<div class="cell">
<div class="inner">2</div>
</div>
<div class="cell">
<div class="inner">3</div>
</div>
<div class="cell">
<div class="inner">4</div>
</div>
<div class="cell">
<div class="inner">5</div>
</div>
<div class="cell">
<div class="inner">6</div>
</div>
</div>
</div>
I have a grid that I'm trying to add a :before Pseudo Element to create a divider line between each grid cell. I only want the divider lines to show in the center cells and not the outside left and right.
I'm able to achieve this using border-right and then using nth-child(3n) to remove borders. But having trouble trying to do the same using a Pseudo Element
.parent {
background: white;
max-width: 600px;
margin: 0 auto;
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
.cell {
position: relative;
&:before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 60%;
width: 1px;
background-color:red;
}
&:nth-child(3n):before {
width: 0;
}
.inner {
max-width: 320px;
width: 320px;
height: 200px;
padding: 57px 43px 40px;
text-align: left;
}
}
}
}

.parnet{
max-width: 600px;
margin: 0 auto;
background: #f4f4f5;
}
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.cell {
position: relative;
}
.inner {
width: 80px;
height: 80px;
padding: 40px;
text-align: left;
}
.wrapper .cell:before{
content: "";
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
height: 60%;
width: 1px;
background-color:red;
}
.wrapper .cell:nth-child(3n):before {
width: 0;
}
<div class="parnet">
<div class="wrapper">
<div class="cell">
<div class="inner">1</div>
</div>
<div class="cell">
<div class="inner">2</div>
</div>
<div class="cell">
<div class="inner">3</div>
</div>
<div class="cell">
<div class="inner">4</div>
</div>
<div class="cell">
<div class="inner">5</div>
</div>
<div class="cell">
<div class="inner">6</div>
</div>
</div>
</div>
So the clue was to set right: 0; on the cell instead of left:0;
Then uses
.wrapper .cell:nth-child(3n):before {
width: 0;
}
Thanks Keith i'm going to score your answer for giving me that great clue.

This is my answer. I'm using the .cell:nth-child(3n):before for the horizontal lines. I hope this is what you need.
.parent {
background: white;
max-width: 600px;
margin: 0 auto;
font-size:2em;
}
.parent .wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.parent .wrapper .cell {
position: relative;
}
.parent .wrapper .cell:before {
content: "";
position: absolute;
right: 50%;
top:.2em;
height: 60%;
width: 1px;
background-color: red;
}
.parent .wrapper .cell:nth-child(3n):before {
width: 300%;
height:1px;
top:100%
}
<div class="parent">
<div class="wrapper">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell">6</div>
<div class="cell">7</div>
<div class="cell">8</div>
<div class="cell">9</div>
</div>
</div>

Related

Two scrolling blocks in flex container

I need to build a card with two scrolling areas. Initial idea was to use flexbox so I came up with this:
.card {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 50%;
min-width: 100px;
min-height: 0;
max-width: 80%;
max-height: 80%;
border: solid 1px black;
padding: 10px;
}
.photo {
background-color: silver;
margin-bottom: 10px;
aspect-ratio: 3;
}
.body {
display: flex;
}
.content {
flex: 1;
display: flex;
flex-direction: column;
margin-right: 10px;
}
.title {
background-color: silver;
margin-bottom: 10px;
}
.text {
flex: 1;
background-color: cyan;
min-height: 0;
overflow: auto;
}
.photos {
width: 100px;
min-height: 0;
overflow: auto;
}
.photos * ~ * {
margin-top: 10px;
}
.thumbnail {
background-color: lightgreen;
aspect-ratio: 3;
}
<div class="card">
<div class="photo">Photo</div>
<div class="body">
<div class="content">
<div class="title">Title</div>
<div class="text" contenteditable>
Full text<br>
Can be multiline and with vertical scroll
</div>
</div>
<div class="photos">
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
</div>
</div>
</div>
link to fiddle: https://jsfiddle.net/SkyLight/jxobz8qn/
The card has maximum width and height and Full text section (cyan one) can have pretty long content so that it should have scroll when needed. Thumbnails section can also have big amount of items so will also need to have scroll.
I know that overflow needs block to have height set in order to work but I can't figure out how to set it properly because the content should be limited mainly by Card's max size.
So can it be achieved with flexbox only or I'll need some other stuff? Would like to achieve the result with pure css.
Make the card element a flexbox container then use flex:1 on the body:
.card {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 50%;
min-width: 100px;
min-height: 0;
max-width: 80%;
max-height: 80%;
border: solid 1px black;
padding: 10px;
/* added */
display: flex;
flex-direction: column;
/**/
}
.photo {
background-color: silver;
margin-bottom: 10px;
aspect-ratio: 3;
}
.body {
display: flex;
flex:1; /* added */
min-height:0; /* added to make sure the content will shrink */
}
.content {
flex: 1;
display: flex;
flex-direction: column;
margin-right: 10px;
}
.title {
background-color: silver;
margin-bottom: 10px;
}
.text {
flex: 1;
background-color: cyan;
min-height: 0;
overflow: auto;
}
.photos {
width: 100px;
min-height: 0;
overflow: auto;
}
.photos * ~ * {
margin-top: 10px;
}
.thumbnail {
background-color: lightgreen;
aspect-ratio: 3;
}
<div class="card">
<div class="photo">Photo</div>
<div class="body">
<div class="content">
<div class="title">Title</div>
<div class="text" contenteditable>
Full text<br>
Can be multiline and with vertical scroll
</div>
</div>
<div class="photos">
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
<div class="thumbnail">Thumbnail</div>
</div>
</div>
</div>

How can I make child of grid take 100% height in Safari?

Help me adjust my code so that it will be working in Safari. Initially I used answer from here with a few adjustments. I needed my card to be responsive and has some additional elements at the bottom.
Here's my code:
.gallery {
display: grid;
gap: 15px;
grid-template-columns: repeat(2, 1fr);
}
.card {
background-color: #fff;
border-radius: 4px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.14);
max-width: 200px;
padding: 10px 10px 20px;
cursor: pointer;
position: relative;
}
.wrapper {
width: 100%;
position: relative;
margin-bottom: 20px;
}
.wrapper::before {
content: '';
padding-bottom: 100%;
display: block;
}
.img-grid {
display: grid;
border-radius: 4px;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 3px;
overflow: hidden;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.img-grid > div {
position: relative;
width: 100%;
height: 100%;
}
.img-grid > div:first-child {
grid-column: 1 / span 2;
}
img {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
}
.logo {
width: 50px;
height: 50px;
background: gainsboro;
float: left;
margin-right: 15px;
}
h4,p {
margin: 3px 0;
}
p {
font-size: 13px;
}
<div class="gallery">
<div class="card">
<div class="wrapper">
<div class="img-grid">
<div>
<img loading="lazy" src="https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510_960_720.jpg"></img>
</div>
<div>
<img loading="lazy" src="https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510_960_720.jpg"></img>
</div>
<div>
<img loading="lazy" src="https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510_960_720.jpg"></img>
</div>
</div>
</div>
<div class="logo"></div>
<h4>Logo name</h4>
<p>Some description</p>
</div>
<div class="card">
<div class="wrapper">
<div class="img-grid">
<div>
<img loading="lazy" src="https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510_960_720.jpg"></img>
</div>
<div>
<img loading="lazy" src="https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510_960_720.jpg"></img>
</div>
<div>
<img loading="lazy" src="https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510_960_720.jpg"></img>
</div>
</div>
</div>
<div class="logo"></div>
<h4>Logo name</h4>
<p>Some description</p>
</div>
</div>
It works fine in Chrome, but it doesn't work in Safari(current and older). It's because I needed my cards to be responsive and always maintain square grid. So I used same trick on the wrapper that's widely used to maintain responsive squares. But as a result of that height: 100% is no longer working in Safari. Is there any way to make it work? I would appreciate some your help.

How to scroll content blocks left and right in css

I am building a scrolling frame on a web page.
The frame is width: 90% of the page-width.
I have a total of 7 blocks but I only want to show 5 at a time with a left & right button for scrolling left and right. Each block is width: 18%
What are the minimum css styles I should consider to get starting building this?
What are the minimum css styles I should consider to get starting
building this?
Is this what are you trying to achieve?
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
body {
text-align: center;
}
.wrapper {
display: inline-block;
width: 90vw;
height: 100px;
background-color: lightgray;
padding: 16px 0;
overflow-x: scroll;
text-align: start;
}
.content {
display: inline-block;
height: 100%;
width: calc(90vw / 5);
text-align: start;
float: left;
}
.content-wrapper {
height: 100%;
width: calc((90vw / 5) * 7);
text-align: start;
}
.buttons-wrapper {
position: absolute;
width: 90vw;
height: calc(100px - 16px);
}
.left-button,
.right-button {
position: absolute;
background-color: black;
width: 30px;
height: 30px;
top: calc(50% - 15px);
color: white;
text-align: center;
}
.left-button {
left: 0;
}
.right-button {
right: 0;
}
<div class="wrapper">
<div class="buttons-wrapper">
<div class="left-button">L</div>
<div class="right-button">R</div>
</div>
<div class="content-wrapper">
<div class="content" style="background-color: red"></div>
<div class="content" style="background-color: orange"></div>
<div class="content" style="background-color: yellow"></div>
<div class="content" style="background-color: green"></div>
<div class="content" style="background-color: lightblue"></div>
<div class="content" style="background-color: blue"></div>
<div class="content" style="background-color: violet"></div>
</div>
</div>

Safari isn't stretching image to flexbox grid

I'm trying to build a simple teaser grid for featured posts on a website using flexbox. It should look like this:
And in FF and Chrome it's all good. If i change the resolution of one image, all the others follow and update their size. But not in Safari. Whatever i do, it never fits to an equal height:
I really don't get the point why this is happening. Each image container on the right has exactly 50% of the height calculated by flexbox. And each image should be stretched to that height.
I could probably achieve this with background-size:cover but i would love to find a solution to use img tags instead.
Here's a demo: https://jsfiddle.net/7tjw8j83/1/
.featured-grid{
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
}
img{
width: 100%;
height: 100%;
display: block;
object-fit:cover;
}
.left{
width: 66.6666%;
}
.right{
width: 33.3333%;
display: flex;
flex-direction: column;
}
.right-top{
background: green;
flex: 1;
}
.right-bottom{
background: red;
flex: 1;
}
<div class="featured-grid">
<div class="left">
<img src="https://unsplash.it/600/450?image=1055">
</div>
<div class="right">
<div class="right-top">
<img src="https://unsplash.it/600/400?image=1051">
</div>
<div class="right-bottom">
<img src="https://unsplash.it/600/400?image=1057">
</div>
</div>
</div>
In addition to Michaels suggestion, you could do like this, where I used background-image instead of img (since you use a given height anyway), and how to add text at an absolute position
html, body {
margin: 0;
}
.featured-grid{
display: flex;
height: 100vh;
}
div {
position: relative;
background-position: center;
background-repeat: no-reapat;
background-size: cover;
overflow: hidden;
}
.left {
width: 66.666%;
}
.right{
width: 33.333%;
display: flex;
flex-direction: column;
}
.right-top{
flex: 1;
}
.right-bottom{
flex: 1;
}
.text {
position: absolute;
left: 10px;
bottom: 10px;
color: white;
}
.text > * {
margin: 5px;
}
<div class="featured-grid">
<div class="left" style="background-image: url(https://unsplash.it/600/450?image=1055)">
<div class="text">
<h2>Title</h2>
<h3>Text</h3>
</div>
</div>
<div class="right">
<div class="right-top" style="background-image: url(https://unsplash.it/600/400?image=1051)">
<div class="text">
<h2>Title</h2>
<h3>Text</h3>
</div>
</div>
<div class="right-bottom" style="background-image: url(https://unsplash.it/600/400?image=1057)">
<div class="text">
<h2>Title</h2>
<h3>Text</h3>
</div>
</div>
</div>
</div>
Updated based on a comment
html, body {
margin: 0;
}
.featured-grid{
display: flex;
height: 100vh;
}
div {
position: relative;
overflow: hidden;
}
img{
width: 100%;
height: 100%;
display: block;
object-fit:cover;
}
.left {
width: 66.666%;
}
.right{
width: 33.333%;
display: flex;
flex-direction: column;
}
.right-top{
flex: 1;
}
.right-bottom{
flex: 1;
}
.text {
position: absolute;
left: 10px;
bottom: 10px;
color: white;
}
.text > * {
margin: 5px;
}
<div class="featured-grid">
<div class="left">
<img src="https://unsplash.it/600/450?image=1055">
<div class="text">
<h2>Title</h2>
<h3>Text</h3>
</div>
</div>
<div class="right">
<div class="right-top">
<img src="https://unsplash.it/600/400?image=1051">
<div class="text">
<h2>Title</h2>
<h3>Text</h3>
</div>
</div>
<div class="right-bottom">
<img src="https://unsplash.it/600/400?image=1057"> <div class="text">
<h2>Title</h2>
<h3>Text</h3>
</div>
</div>
</div>
</div>
Updated (2:nd) based on a comment
html,
body {
margin: 0;
}
.featured-grid {
display: flex;
}
div {
position: relative;
overflow: hidden;
}
img {
visibility: hidden;
display: block;
}
img.show {
position: absolute;
visibility: visible;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
.left img {
max-height: 100vh;
}
.right img {
max-height: 50vh;
}
.left {
width: 66.666%;
}
.right {
width: 33.333%;
display: flex;
flex-direction: column;
}
.right-top {
flex: 1;
}
.right-bottom {
flex: 1;
}
.text {
position: absolute;
left: 10px;
bottom: 10px;
color: white;
}
.text > * {
margin: 5px;
}
<div class="featured-grid">
<div class="left">
<img src="https://unsplash.it/300/250?image=1055">
<img class="show" src="https://unsplash.it/300/250?image=1055">
<div class="text">
<h2>Title 1</h2>
<h3>Text 1</h3>
</div>
</div>
<div class="right">
<div class="right-top">
<img src="https://unsplash.it/300/200?image=1057">
<img class="show" src="https://unsplash.it/300/200?image=1057">
<div class="text">
<h2>Title 2</h2>
<h3>Text 2</h3>
</div>
</div>
<div class="right-bottom">
<img src="https://unsplash.it/300/200?image=1057">
<img class="show" src="https://unsplash.it/300/200?image=1057">
<div class="text">
<h2>Title 3</h2>
<h3>Text 3</h3>
</div>
</div>
</div>
</div>

float divs with clear & fill width

I have a problem, i want to set 3 floated divs and on the bottom I would like to have a footer. So I got these two solutions, but it does not work. Please check out the image:
Here the problem is that the content is not not cleared, so the footer does not change position:
<div class="container">
<div class="left"><div class="content"><div class="right">
<div style="clear:left;"></div>
</div>
<div class="footer"></div>
.container {
height: auto !important;
min-height: 100%;
}
.left {
float: left;
width: 20%;
max-width: 200px;
}
.center {
float: left;
width: 80%;
max-width: 500px;
}
.right {
width: auto;
}
.content {
height: auto !important;
height: 100%;
min-height: 100%;
}
.footer {
height: 202px;
margin: -202px auto 0;
position: relative;
}
If i clear the content, I get the result that the right div goes to the next line:
thanks!
I played around a little bit. I think your html structure wasn't right for the effect you were trying to create.
Here is a new example:
HTML
<div class="container">
<div class="left">
</div>
<div class="center">
</div>
<div class="right">
</div>
<div style="clear">
<div class="content">
</div>
<div class="footer">
</div>
</div>
CSS
.container {
height: auto !important;
min-height: 100%;
}
.left {
float: left;
width: 20%;
max-width: 200px;
min-height: 100px;
background: red;
}
.center {
float: left;
width: 80%;
max-width: 500px;
min-height: 100px;
background: blue;
}
.right {
width: auto;
min-height: 100px;
background: green;
}
.content {
height: auto !important;
height: 100%;
min-height: 100px;
width: 80%;
max-width: 500px;
margin: 0 auto;
background: yellow;
}
.footer {
height: 202px;
margin: 0 auto;
position: relative;
background: purple;
}
I rearanged everything in this fiddle:
http://jsfiddle.net/LJQCx/2/
I hope this is what you trying to achiev.
Here is the code hope it will help check the fiddle
<div class="page-wrap">
<div class="container">
<div class="left">
<p>I am Left</p>
</div>
<div class="center">
<p>I am Center</p>
</div>
<div class="right">
<p>I am Right</p>
</div>
<div class="clear"></div>
</div>
</div>
<div class="footer">
<p>I am Footer</p>
</div>
* { margin: 0;}
html, body { height: 100%;}
.page-wrap {min-height: 100%;/* equal to footer height */margin-bottom: -142px; }
.page-wrap:after { content: ""; display: block;}
.footer, .page-wrap:after { /* .push must be the same height as footer */ height: 142px;}
.site-footer {}
.container{ width:100%;}
.left{ float:left; width:25%;}
.center{float:left; width:50%;}
.right{float:left; width:25%;}

Resources