I'm having some problems when trying to reorder columns using bootstrap, HTML and CSS.
Currently, my layout is something like this:
B and C are contained inside a single column, while A has a column for itself. On desktop and tablets it's okay like that, but I need to reorder the content for small devices to get something like this:
My code is currently like this:
<div class="container">
<div class="row padding-m">
<div class="col-md-6">
<div class="card" style="padding: 0px 20px;">
BLOCK A
</div>
</div>
<div class="col-md-6">
<div class="card" style="border: none;">
BLOCK B
BLOCK C
</div>
</div>
</div>
</div>
So my problem is that, on one hand, I would need to split column 2 in two parts, and on the other, I would need B to move to the top of the column and C to move to the bottom. Is there any way of doing this?
Assuming "A" is taller as in your picture, just use pull-right on the other columns, and col-xs-12 to ensure full width on mobile...
Demo
<div class="row">
<div class="col-xs-12 col-md-6 pull-right">
<div>
B
</div>
</div>
<div class="col-xs-12 col-md-6">
<div>
A
</div>
</div>
<div class="col-xs-12 col-md-6 pull-right">
<div>
C
</div>
</div>
</div>
Demo
With bootstrap 4 pull-right doesn't work anymore, and it also isn't compatible with flex.
Solution compatible with flex can be based on:
display: contents causes an element's children to appear as if they were direct children of the element's parent, ignoring the element itself. This can be useful when a wrapper element should be ignored when using CSS grid or similar layout techniques.
order: -1 for reordering "B" element.
Complete code for pure HTML+CSS solution without any libraries:
* {
box-sizing: border-box;
}
.main-container {
display: flex;
}
.item {
width: 50%;
}
.photo-container {
background: #AAF;
display: flex;
align-items: center;
justify-content: space-around;
padding: 1rem;
}
.photo {
background: #55F;
width: 140px;
height: 220px;
border: solid 1px #33F;
}
.product-details h1 {
background: #FAA;
margin: 0;
padding: 1rem;
}
.product-description {
background: #FFA;
padding: 1rem;
}
#media (max-width: 600px) {
.main-container {
flex-direction: column;
}
.item {
width: 100%;
}
.product-details {
display: contents;
}
.product-details h1 {
order: -1;
}
}
<div class="main-container">
<div class="item photo-container">
<div class="photo"></div>
</div>
<div class="item product-details">
<h1>Product name</h1>
<div class="product-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
</div>
Solution based on bootstrap 4:
* {
box-sizing: border-box;
}
.photo-container {
background: #AAF;
display: flex;
align-items: center;
justify-content: space-around;
}
.photo {
background: #55F;
width: 140px;
height: 220px;
border: solid 1px #33F;
}
.product-details h1 {
background: #FAA;
}
.product-description {
background: #FFA;
}
#media (max-width: 576px) {
.product-details {
display: contents;
}
.product-details h1 {
order: -1;
}
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row flex-column flex-sm-row">
<div class="col-12 col-sm-6 photo-container">
<div class="photo"></div>
</div>
<div class="col-12 col-sm-6 product-details">
<h1>Product name</h1>
<div class="product-description">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
</div>
</div>
Related
I'm fairly new to CSS Flexbox but I'm trying to create a horizontal card, where an image is on the left, and text/buttons are on the right. When the site is scaled down (for mobile use), the row items should wrap and the image should sit on top of the text. I've tried setting the wrap property to wrap but it wraps for large screens when it should only wrap for smaller screens. See code below:
* {
margin: 0;
padding: 0;
}
#box {
padding: 20px;
}
img {
width: 200px;
}
#outer-container {
display: flex;
flex-wrap: wrap;
border: solid 1px;
width: 70%;
margin: auto;
}
#inner-container {
border: solid 1px;
display: flex;
justify-content: space-between;
flex-direction: column;
}
<div id="outer-container">
<img src="https://icatcare.org/app/uploads/2018/07/Thinking-of-getting-a-cat.png" alt="cat">
<div id="inner-container">
<div>
<h3>Heading</h3>
<br>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div>
Other stuff
</div>
</div>
</div>
Should I attempt to use another approach (like Bootstrap's card layouts) or is there something obvious I'm missing?
Set a flex-basis to the text container to control when the wrap should happen.
Open the below on full screen and resize to see:
* {
margin: 0;
padding: 0;
}
#box {
padding: 20px;
}
img {
width: 200px;
}
#outer-container {
display: flex;
flex-wrap: wrap;
border: solid 1px;
width: 70%;
margin: auto;
}
#inner-container {
border: solid 1px;
display: flex;
justify-content: space-between;
flex-direction: column;
flex-basis:500px;
flex-grow:1;
}
<div id="outer-container">
<img src="https://icatcare.org/app/uploads/2018/07/Thinking-of-getting-a-cat.png" alt="cat">
<div id="inner-container">
<div>
<h3>Heading</h3>
<br>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div>
Other stuff
</div>
</div>
</div>
The image is on the left.
The text is on the right.
As soon as the first line of text reaches the right side of the container, the entire item will wrap.
It's tempting to think that once the first line reaches the right-side limit, just the text will wrap.
That's not how it works.
That touch will trigger the entire item to wrap.
Try it out: jsFiddle demo
#outer-container {
display: flex;
flex-wrap: wrap;
border: solid 1px;
}
#inner-container {
border: solid 1px;
display: flex;
min-width: 0;
}
<div id="outer-container">
<img src="https://icatcare.org/app/uploads/2018/07/Thinking-of-getting-a-cat.png" width=50 height=50 alt="cat">
<div id="inner-container">
<p>Re-size the screen. Once this text touches the right side, the item will wrap.</p>
</div>
</div>
Use a media query to control the wrapping behavior.
Assuming I understood your question correctly, I believe I've come up with something that resembles a solution.
I altered your code ever so slighty, and worked with the flex-direction attritube. Basically what I've done is, when you're on desktop version, your card used the attribute flex-direction: row to have your items inside of your div be aligned like you described.
When you swicth to mobile version, the only thing I've done is add a media query that tells the div to use the flex-direction: column, in order to have the items inside you div be aligned like you described.
In this solution, you avoid switching to Bootstrap, by utilizing flexbox and the use of media queries like #DevLover mentioned.
* {
margin: 0;
padding: 0;
}
#box {
padding: 20px;
}
img {
width: 200px;
}
#outer-container {
display: flex;
border: solid 1px;
width: 70%;
flex-direction: row;
}
#inner-container {
border: solid 1px;
}
#media only screen and (max-width: 768px) {
#outer-container {
flex-direction: column;
}
}
<div id="outer-container">
<img src="https://icatcare.org/app/uploads/2018/07/Thinking-of-getting-a-cat.png" alt="cat">
<div id="inner-container">
<h3>Heading</h3>
<br>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<div>
Other stuff
</div>
</div>
</div>
I hope this solves your issue!
HTML:
<div id="outer-container">
<div class="content-wrapper">
<img src="https://icatcare.org/app/uploads/2018/07/Thinking-of-getting-a-cat.png" alt="cat">
<div id="inner-container">
<div>
<h3>Heading</h3>
<br>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div>
Other stuff
</div>
</div>
</div>
</div>
CSS:
* {
margin: 0;
padding: 0;
}
#box {
padding: 20px;
}
img {
width: 100%;
object-fit: cover;
}
#outer-container {
display: flex;
flex-wrap: wrap;
border: solid 1px;
width: 70%;
margin: auto;
}
#inner-container {
border: solid 1px;
display: flex;
justify-content: space-between;
flex-direction: column;
}
.content-wrapper {
display: flex;
flex-direction: column;
}
#media only screen and (min-width: 767px) {
.content-wrapper {
flex-direction: row;
}
img {
width: 200px;
}
}
I'm using grid layout in CSS and I have a span, with a grid on the bottom.
Each cell of my grid have a centered content and i would like to add padding on left and right to my text for being align with the content of cell in both side.
I would like a full css solution, but i'm not sure if it's possible...
<span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</span>
<div class="grid-container grid-container--fill">
<div class="grid-element">
<div class="inner">
</div>
</div>
<div class="grid-element">
<div class="inner">
</div>
</div>
<div class="grid-element">
<div class="inner">
</div>
</div>
<div class="grid-element">
<div class="inner">
</div>
</div>
</div>
Here is a jsfiddle if u want to try some stuff :
https://jsfiddle.net/s4Lxwrm5/
Here you go buddy:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.container {
width: 100%;
height: auto;
position: relative;
display: block;
overflow: auto;
background-color: grey;
}
.container-inner {
width: 100%;
max-width: 1248px; /* SET YOUR MAX WIDTH */
height: auto;
margin: 0 auto;
padding: 20px; /* SET YOUR PADDING */
position: relative;
display: block;
overflow: auto;
background-color: orange;
}
.text-container {
width: 100%;
height: auto;
margin: 0 auto 20px auto;
padding-left: calc((100% / 4) / 10); /* WORK OUT THE WIDTH OF ONE GRID BOX BY DIVIDING BY THE NUMBER OF BOXES YOU ARE 'gridding'. THEN DIVIDING BY 10 WILL GIVE YOU THE 10% PADDING THAT I SPECIFY LATER ON IN THE CSS */
padding-right: calc((100% / 4) / 10); /* WORK OUT THE WIDTH OF ONE GRID BOX BY DIVIDING BY THE NUMBER OF BOXES YOU ARE 'gridding'. THEN DIVIDING BY 10 WILL GIVE YOU THE 10% PADDING THAT I SPECIFY LATER ON IN THE CSS */
position: relative;
text-align: justify;
background-color: red;
}
.supporting-boxes {
width: 100%;
height: auto;
position: relative;
display: grid;
grid-template-columns: repeat(auto-fill, 25%);
background-color: green;
}
.grid-box {
width: 80%; /* LEAVING 10% PADDING */
height: auto;
min-height: 200px;
position: relative;
justify-self: center;
background-color: purple;
}
.box-content {
width: 100%;
height: auto;
text-align: center;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: pink;
}
<div class="container">
<div class="container-inner">
<div class="text-container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="supporting-boxes">
<div class="grid-box">
<div class="box-content">
A
</div>
</div>
<div class="grid-box">
<div class="box-content">
B
</div>
</div>
<div class="grid-box">
<div class="box-content">
C
</div>
</div>
<div class="grid-box">
<div class="box-content">
D
</div>
</div>
</div>
</div>
</div>
This is quite volatile code though, if you're changing the number of boxes and stuff we may need to look for another solution.
I'm trying to create a layout that's similar to this: the image and text should be side-by-side on desktop and tablet. On mobile, they should show up in one column with either the image or the text on top and the other below it. I'm using the Horizontal Cards from Materialize CSS to do this. However, on mobile, the cards still show up in a horizontal format. Is there any way to change this using Materialize CSS?
This is my current code:
<div class="col s12 m6 l6">
<div class="card horizontal">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1454994834218-5ffbb76c0e74?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=dddc4ee524eee04e325dbc73367391d8">
</div>
<div class="card-stacked">
<div class="card-content valign-wrapper">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="card-action">
Sample Link
</div>
</div>
</div>
</div>
<style>
.card-content{
margin:0 30% 0 30px;
}
</style>
I've also tried the codes here, but the image gets cut off and the card layout is still horizontal even on mobile.
<div class="sample">
<div class="row">
<div class="col s12 m6 l6 left-image">
</div><!-- /col s12 m6 left-image -->
<div class="col s12 m6 l6 text-right">
<div class="test">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div><!-- /col s12 m6 icon-text -->
</div><!-- /col s12 m6 text-right -->
</div><!-- /row -->
</div>
<style>
.sample>.row{
display:flex;
}
.sample>.row>.col{
align-items: center;
display: flex;
flex: 1;
justify-content:center;
text-align: center;
}
.sample>.row>.col.left-image{
background:url("https://images.unsplash.com/photo-1454994834218-5ffbb76c0e74?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=dddc4ee524eee04e325dbc73367391d8");
background-size:cover;
height: auto;
}
</style>
Also, is there a way to keep the image and the text aligned or with nearly the same height on desktop and tablet, but without cutting off the image?
There is a pull request on GitHub that implements exactly what you want.
The Pull request is written in sass. This is what it compiles to:
#media only screen and (min-width: 601px) {
.card.responsive-horizontal {
display: flex;
}
.card.responsive-horizontal.small .card-image, .card.responsive-horizontal.medium .card-image, .card.responsive-horizontal.large .card-image {
height: 100%;
max-height: none;
overflow: visible;
}
.card.responsive-horizontal.small .card-image img, .card.responsive-horizontal.medium .card-image img, .card.responsive-horizontal.large .card-image img {
max-height: 100%;
width: auto;
}
.card.responsive-horizontal .card-image {
max-width: 50%;
}
.card.responsive-horizontal .card-image img {
border-radius: 2px 0 0 2px;
width: auto;
max-width: 100%;
}
.card.responsive-horizontal .card-stacked {
position: relative;
display: flex;
flex-direction: column;
flex: 1;
}
.card.responsive-horizontal .card-stacked .card-content {
flex-grow: 1;
}
}
If you are looking for the sass version of this or you want more information, have a look at the pull request on GitHub.
I'm trying to create 2 columns, one simply filled with text while the other contains three coloured boxes of equal height (33.33%) which then add up to the same height as the text. The overall size of the container can't be a fixed height unfortunately as the site is responsive and the amount of text may change so I need the height of the two columns to be flexible.
Now I've used display: table; and display: table-cell; elsewhere in the site to achieve equal height between just two columns but am struggling to make this one work with the three equally sized boxes within one of the columns.
I've made a JSFiddle to show you what I've got:
http://jsfiddle.net/56yFp/
And here's the html:
<div class="column-row">
<div class="column column-cell column-text">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div class="column column-cell column-boxes">
<div class="box green-box">Box 1</div>
<div class="box red-box">Box 2</div>
<div class="box blue-box">Box 3</div>
</div>
</div>
css:
.page-wrapper {
background-color: #FFFFFF;
}
/* Table */
.column-table {
display: table;
}
.column-row {
display: table-row;
}
.column-cell {
display: table-cell;
}
.column {
vertical-align: middle;
height: 100%;
}
.column-text {
width: 62.5%;
background-color: #e2e2e2;
}
.column-boxes {
width: 37.5%;
}
.box {
min-height: 33.33%;
width: 100%;
}
/* Colors */
.green-box {
background-color: #016354;
}
.red-box {
background-color: #eb5640;
}
.blue-box {
background-color: #93ceee;
}
Any thoughts SO community? Thanks
DEMO
.column {
display:inline-block
}
First, this is my HTML
<div class="header">
<div class="wrapper">
<div class="navi">
Logo
<ul><!--
--><li>Link 1</li><!--
--><li>Link 2</li><!--
--></ul>
</div>
</div>
</div>
<div class="wrapper">
<div class="content">
<p>"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
</div>
</div>
and CSS
.wrapper {
width: 90%;
max-width: 50em;
margin: 0 auto;
}
.header,
.navi {
width: 100%;
}
.header {
background: grey;
}
.navi {
background: green;
display: table;
text-align: center;
}
.navi ul {
display: table-cell;
vertical-align: middle;
text-align: right;
}
.navi li {
background: orange;
display: inline;
margin-left: 10px;
}
.navilink {
display: inline-block;
width: auto;
}
.logo {
background: red;
float: left;
}
.content {
width: 100%;
background: fuchsia;
}
Fiddle
Fullscreen Fiddle
You see, the wrapper ensures that there is always some kind of gap between content and edge of the viewport and beyond a certain point (50 em), the .wrapper doesn't exceeds any further.
The code I posted here works, but I would like to know if there is any chance to get rid of <div class="wrapper"> achieving the same result. I already tried to apply the .wrapper class directly to the elements, but that isn't working - why?
To clarify: My aim is it to make the markup cleaner. That's why I am interested in a solution then ensures that the elements behave like in the example I posted, but without the use of <div class="wrapper">. The class .wrapper has to stay of course, it's just that div that strikes me. Thats why I tried to add .wrapper directly to the elements.
Remove the wrapper div, and add the two CSS properties to the content div..
.content {
margin: 0 auto;
max-width: 50em;
}