So this might seem like an obvious question to some, but what is the best practice for aligning versatile span content in a responsive grid? I know you could simply set a pixel height, but wouldn't that kind of defeat the purpose of keeping things responsive?
Take the below screenshot for instance:
<div class="container">
<div class="row">
<div class="span3 well"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec facilisis venenatis sollicitudin. Nam eros risus, lobortis a ultricies sed, interdum in mi. Donec elementum ullamcorper odio, vel gravida velit pretium quis. Donec sagittis, sem nec rhoncus tristique, dui ante volutpat nisl, sit amet feugiat velit lorem sagittis turpis. Quisque laoreet arcu et sapien volutpat nec porta augue iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan feugiat libero, vel fringilla neque euismod vitae. Nullam justo mi, faucibus sagittis pharetra non, egestas sit amet nulla.</p></div>
<div class="span3 well"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec facilisis venenatis sollicitudin. Nam eros risus, lobortis a ultricies sed, interdum in mi. Donec elementum ullamcorper odio, vel gravida velit pretium quis. Donec sagittis, sem nec rhoncus tristique, dui ante volutpat nisl, sit amet feugiat velit lorem sagittis turpis. Quisque laoreet arcu et sapien volutpat nec porta augue iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan feugiat libero, vel fringilla neque euismod vitae. Nullam justo mi, faucibus sagittis pharetra.</p> </div>
<div class="span3 well"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec facilisis venenatis sollicitudin. Nam eros risus, lobortis a ultricies sed, interdum in mi. Donec elementum ullamcorper odio, vel gravida velit pretium quis. Donec sagittis, sem nec rhoncus tristique, dui ante volutpat nisl, sit amet feugiat velit lorem sagittis turpis. Quisque laoreet arcu et sapien volutpat nec porta augue iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean accumsan feugiat libero.</p> </div>
</div>
</div>
You can find the relevant JSfiddle here.
Note: Responsiveness seems to be broken in this JSFiddle for some reason, works fine in my own Twitter Bootstrap application however.
If you take a look on DigitalLabs which is a website I worked on then if you look at the profiles I came across a similar error - i wanted them all to be the same height.
See my JSFiddle here:
http://jsfiddle.net/LDtRr/2/
(scroll down to the bottom and press resize to see them all dynamically resize)
I used some javascript to fix the heights - I will show you the code that I used.
function resize(resize, resizeinner) {
var max = 0;
//reset height back to 0
$(resize).each(function(index, element) {
$(element).css({ 'height' : '0' });
});
//find height of the profiles
$(resizeinner).each(function(index, element) {
var height = $(element).height();
console.log(' height=' + height);
if(height > max) {
max = height;
}
});
//set the height dynamically based on the maximum so they are all uniform
$(resize).each(function(index, element) {
$(element).css({ 'height' : max });
console.log(' resizedTo=' + $(element).height());
});
console.log('max - ' + max);
}
Then for the html i used
<div class="span4">
<div class="well profile">
<div class="profile-resize">
<!-- content -->
</div>
</div>
</div>
What the code does is it gets the maximum height for the divs with the profile class, then sets all of the divs with that class to the maximum height - you can also bind this to the window resize so it automatically resizes the heights with the window.
$(window).load(function() {
//initially size the elements
resize('.profile', '.profile-resize');
});
Maybe not the most elegant solution but I couldnt think of a better one at the time.
Although your markup doesn't keep the hierarchy recommended by the bootstrap doc (.container > .row > .span > .well), have you thought about absolute positioning ? No JS involved.
Demo (jsfiddle)
<div class="container" style="position: relative;">
<div class="row faux-row">
<div class="span3 well"></div>
<div class="span3 well"></div>
<div class="span3 well"></div>
</div>
<div class="row vrai-row">
<div class="span3"><p>...</p></div>
<div class="span3"><p>...</p></div>
<div class="span3"><p>...</p></div>
</div>
</div>
.vrai-row { position: relative;z-index: 101; }
.faux-row { position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 100; }
.faux-row .well {
height: 100%;
/* The following is because .span* elements should not have paddings, margins nor borders see http://stackoverflow.com/a/11299934/1478467 */
box-sizing: border-box;
}
If you want to set padding, margin, borders (styling that actually take space), it should be applied to the real one and the faux one - not the columns themselves, but their children for example.
The downside is that (as it is in the demo) you have to stick to the non-responsive grid (fluid or static). But it should work with a few more rules encapsulated in media queries.
Update
Responsiveness is actually not so hard to get, if you keep the .well class on all spans :
Demo responsive (jsfiddle)
#media (max-width: 767px) {
.faux-row { display: none!important; }
}
#media (min-width: 768px) {
.vrai-row .well { /* Deactivate well styles */
background-color: transparent;
border-color: transparent;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
}
Related
I'm struggling with creating a dynamic layout which is different for mobile and desktop. The items should be different sorted based on the screen width and the layout should change.
Below is the main objective, where the left layout is for mobile and the right one is desktop:
The content of the blue, purple and yellow div can vary so the height is adjustable. The purple and yellow block must always be on the side of the gray + blue block on desktop.
Right now I have it working for only 3 columns but the 'dynamic' height is duplicated on all columns: Bootstrap 4: sidebar between columns on mobile. Columns under each other layout
To give you a clear idea of the possibilities here are some desktop variations:
I've managed to get it working with floats but the columns align on each other. Also have fixed it with a static max-height for the parent and use column wrap but I don't want to use a static max-height since the content should have a dynamic height..
I don't want to use some glitchy javascript or unsupported grid-css.
Looking forward to ideas/suggestions! Cheers.
You should be able to get this layout to work with a combination of CSS columns (not CSS grid) on "desktop", and flexbox on "mobile".
<div class="container">
<div class="d-flex d-md-columns flex-column min-vh-100">
<div class="d-md-inline-block light order-0">
light
</div>
<div class="d-md-inline-block blue order-2">
blue
</div>
<div class="d-md-inline-block purple order-1">
purple
</div>
<div class="d-md-inline-block yellow order-3">
yellow
</div>
</div>
</div>
The only extra CSS you'll need is a media query for the columns on larger (md) desktop widths. The the flexbox ordering will kick-in on mobile..
#media (min-width: 768px) {
.d-md-columns {
display: inline-block !important;
column-count: 2;
-webkit-column-gap: 0
-moz-column-gap: 0;
column-gap: 0;
}
}
https://codeply.com/go/QWIlredUTk
This works specifically for this 4 column layout. However, generally speaking flexbox columns do NOT fit together vertically like a "masonry" layout: Is it possible for flex items to align tightly to the items above them?
I think there is no pure CSS solution for this (at least without using CSS-grid or display:contents). Every CSS way I thought had bugs: float & column flexbox simple don't work in this particular case.
Column flexbox cannot wrap correctly an item if we work with a content without fix height and float can't create a "masonry" layout. Also Bootstrap card-columns are not a solution because your main objective is to align left and right column in height.
I know, you don't want glitchy javascript, but I think it is necessary to create your layout. So, I post you my solution (a jquery solution) without use any d-none class to prevent duplicate HTML & SEO problems.
Moreover, you are using Bootstrap and this framework makes extensive use of jQuery so, I think, it not a problem to ask jQuery for a little help. This help:
function move(){
if($(".main .col-lg-8").css('display')=='block'){
$('.purple').insertAfter('.gray');
} else {
$('.purple').insertBefore('.yellow');
}
}
$(window).resize(function(){move()})
$(document).ready(function(){move()})
To move our purple div in second position when .col-lg-8 have display:block
This is all code in action:
function move(){
if($(".main .col-lg-8").css('display')=='block'){
$('.purple').insertAfter('.gray');
} else {
$('.purple').insertBefore('.yellow');
}
}
$(window).resize(function(){move()})
$(document).ready(function(){move()})
.gray{
background-color: gray;
}
.blue{
background-color: blue;
}
.purple{
background-color: purple;
}
.yellow{
background-color: yellow;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<div class="container mt-5">
<div class="row main">
<div class="col-lg-4 d-lg-flex flex-lg-column">
<div class="gray mb-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sodales finibus faucibus. Morbi blandit neque a diam laoreet pellentesque. Vivamus in orci sed turpis posuere iaculis quis sed augue. Curabitur lorem magna, bibendum vitae vestibulum nec faucibus. Morbi blandit neque a diam laoreet pellentesque. Vivamus in orci sed turpis posuere iaculis quis sed augue. Curabitur lorem magna, bibendum vitae vestibulum nec, feugiat eget justo. Ut aliquam quis velit non euismod. Ut vehicula, sem quis cursus pretium, purus libero tincidunt eros, vitae hendrerit nisi mi vitae erat. Curabitur augue purus, sagittis tempor volutpat quis, congue sed mi. Sed gravida odio sed orci iaculis tincidunt. Etiam ac mauris sit amet turpis consequat fermentum ut vitae sem. Aliquam tincidunt convallis sem.</div>
<div class="blue flex-fill mb-4 mb-lg-0">
Lorem ipsum dolor sit amet, consectetur.Quisque sodales finibus </div>
</div>
<div class="col-lg-8 d-lg-flex flex-lg-column">
<div class="purple mb-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. faucibus. Morbi blandit neque a diam laoreet pellentesque. Vivamus in orci sed turpis posuere iaculis quis sed augue. Curabitur lorem magna, bibendum vitae vestibulum nec, feugiat eget justo. Ut aliquam quis velit non euismod. Ut vehicula, sem quis cursus pretium, purus libero tincidunt eros, vitae hendrerit nisi mi vitae erat. Curabitur augue purus, sagittis tempor volutpat quis, congue sed mi. Sed gravida odio sed orci iaculis tincidunt. Etiam ac mauris sit amet turpis consequat fermentum ut vitae sem. Aliquam tincidunt convallis sem. </div>
<div class="yellow flex-fill">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
</div>
</div>
</div>
Waiting a pure CSS solution, this could be a way.
Question Information
Here I have a Bootstrap (Version 4.0.0 beta 2) alert with a margin of 5% on each side. I also have three W3.CSS cards nested inside a w3 container that are each 31% of the container size and a 1% margin on each side per card.
Desired Result:
I want the card's container to have a 5% margin on each side with each of the cards having a 1% margin in between each. So far the two cards on the left and right do not have the same margin with the alert on top.
Current Result:
Expected Result:
HTML:
<div class="alert alert-success" role="alert" style="overflow: hidden;">
This is the bootsrap alert I want the column's container to have the same 5% margin on both sides as.
</div>
<div class="w3-container">
<div class="w3-panel w3-card w3-yellow">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mattis dapibus aliquam. Nam ornare mollis sodales. In mollis in elit ac eleifend. Integer ac volutpat nisl, id cursus lorem. Aenean pellentesque volutpat tortor in porttitor. Cras ultrices
augue sit amet scelerisque hendrerit. Cras vel neque et justo posuere tempus volutpat pharetra lectus. Nam luctus condimentum bibendum.</p>
</div>
<div class="w3-panel w3-card-2 w3-yellow">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mattis dapibus aliquam. Nam ornare mollis sodales. In mollis in elit ac eleifend. Integer ac volutpat nisl, id cursus lorem. Aenean pellentesque volutpat tortor in porttitor. Cras ultrices
augue sit amet scelerisque hendrerit. Cras vel neque et justo posuere tempus volutpat pharetra lectus. Nam luctus condimentum bibendum.</p>
</div>
<div class="w3-panel w3-card-4 w3-yellow">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mattis dapibus aliquam. Nam ornare mollis sodales. In mollis in elit ac eleifend. Integer ac volutpat nisl, id cursus lorem. Aenean pellentesque volutpat tortor in porttitor. Cras ultrices
augue sit amet scelerisque hendrerit. Cras vel neque et justo posuere tempus volutpat pharetra lectus. Nam luctus condimentum bibendum.</p>
</div>
</div>
CSS:
.alert {
margin-top: 10px;
margin-right: 5%;
margin-left: 5%;
color: #fff;
border: none;
background-color: #2ecc71;
}
.w3-container {
margin: 0 5%;
}
.w3-card,
.w3-card-2,
.w3-card-4 {
float: left;
width: 31%;
margin: 0 1%;
padding: 20px;
}
I have also provided a JSFiddle Demo
Since you'r targeting the .w3-container, which is a parent of the w3-cards, you should be using padding instead of a margin:
.w3-container {
padding: 0 4%;
}
I've set 4% for the left/right padding because of the 1% left/right margin of the w3-cards.
I've also changed the width of the w3-cards to 31.33% for accuracy and to remove the undesired space.
Updated fiddle
I am making a list of blurbs with images that can be used anywhere throughout our site. I want it to be really flexible, not have a specified width, and work properly with no image and with different sizes of images. If the text for a block is longer than its image, I want the text not to wrap under the image.
I made a fiddle of pretty much exactly how I want it. https://jsfiddle.net/4dbgnqha/1/
Now the problem is, our senior developer told me I can't use overflow:hidden to clear the float or to prevent the wrap because:
"Overflow hidden spawns an object to wrap around the element you specified that on. By doing so it is able to constrain the perceived viewable area on that element. This invokes quarks mode in IE, which has a cascading effect for other elements on that page and how they will be interprited"
So whether or not I agree with that, I can't use it. I also can't use a clearfix hack because he said:
"clearfix dumps before:: and after:: elements into the DOM, we don’t want this sort of thing to be complicating layout, especially when we’re traversing through the DOM dealing with dynamically added elements and potential 3rd party code"
Now, I tried to find a way to build the layout without these hacks, but I haven't quite been able to get it with the constraints I want (no fixed width on the images, or the container).
Here's the sample CSS (with the "hacks"):
.item {
overflow: hidden;
margin-bottom: 20px;
}
.item img {
float:left;
margin-right: 10px;
}
.item p {
margin: 0;
overflow: hidden;
}
For this specific example you could use display: table-row / table-cell (unless your dev has a beef with this too)...
.item {
margin-bottom: 20px;
display: table;
}
.item img {
margin-right: 10px;
display: table-cell;
vertical-align: top;
}
.item p {
margin: 0;
display: table-cell;
vertical-align: top;
}
<div class="container">
<div class="item">
<img src="//placehold.it/100x100">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum porttitor nisi purus, eu pretium ipsum ultricies eu. Nulla eleifend arcu dolor, et vestibulum ligula lacinia sed. Sed viverra tortor lorem, molestie volutpat nisi volutpat a. Suspendisse dolor lacus, ultrices eu quam vel, lobortis placerat nibh.</p>
</div>
<div class="item">
<img src="//placehold.it/150x100">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="item">
<img src="//placehold.it/100x200">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum porttitor nisi purus, eu pretium ipsum ultricies eu. Nulla eleifend arcu dolor, et vestibulum ligula lacinia sed. Sed viverra tortor lorem, molestie volutpat nisi volutpat a. Suspendisse dolor lacus, ultrices eu quam vel, lobortis placerat nibh.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum porttitor nisi purus, eu pretium ipsum ultricies eu. Nulla eleifend arcu dolor, et vestibulum ligula lacinia sed. Sed viverra tortor lorem, molestie volutpat nisi volutpat a. Suspendisse dolor lacus, ultrices eu quam vel, lobortis placerat nibh.</p>
</div>
<div class="item">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum porttitor nisi purus, eu pretium ipsum ultricies eu. Nulla eleifend arcu dolor, et vestibulum ligula lacinia sed. Sed viverra tortor lorem, molestie volutpat nisi volutpat a. Suspendisse dolor lacus, ultrices eu quam vel, lobortis placerat nibh.</p>
</div>
<div class="item">
<img src="//placehold.it/100x100">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum porttitor nisi purus, eu pretium ipsum ultricies eu. Nulla eleifend arcu dolor, et vestibulum ligula lacinia sed. Sed viverra tortor lorem, molestie volutpat nisi volutpat a. Suspendisse dolor lacus, ultrices eu quam vel, lobortis placerat nibh.</p>
</div>
</div>
Fiddle version
Browser support is pretty universal - CANIUSE
I am attempting to write a userstyle to reformat another website (no chance to change html).
Currently the website has main content on left with a full height sidebar on RHS.
I have used CSS to remove much of the sidebar content and would now like the main content to expand to fill the width of the area below the sidebar.
If I had control of the HTML source I would place the sidebar first with 'float: right' in the style but I don't have control of the source and the sidebar div is after main content.
Traditionally this couldn't be done in CSS but can it be done now using CSS3? and if so how?
The pages I am actually attempting to style are TripAdvisor Forum pages such as this one but they are overly complicated to attempt use as an example so I have created this very simple web page to play with:
<!DOCTYPE html>
<html>
<head>
<style>
#mainbody {
border: 2px solid blue;
width: 600px;
}
#sidebar {
border: 2px solid green;
position: inherit;
float: right;
width: 250px;
}
#content {
position: inherit;
width: 550px;
}
</style>
</head>
<body>
<div id=mainbody>
<div id=content>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper
porta. Mauris massa. </p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper
porta. Mauris massa. </p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper
porta. Mauris massa.</p>
</div>
<div id=sidebar>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper
porta. Mauris massa. </p>
</div>
</div>
</body>
</html>}
With sidebar above content I get the desired format
Using jQuery you can do this:
$("#content").insertAfter("#sidebar");
http://jsbin.com/juvoc/1/edit
I have this link to my jsfiddle code
I am trying to format the columns of the grid to have the same height on both sides and other grids to line up correctly underneath. In this example the half column has more info (the heights are different). I want the other half to have the same height. Is this achievable?
Thanks, the code is as follows:
<style>
#page {
width:95%;
text-align:center;
margin:auto;
}
#row {
height:100%
}
#header {
width:100%;
background-color: rgb(0, 143, 213);
height:50px;
}
#full {
width:99%;
margin:0.5%;
background-color:blue;
}
#half {
width:48%;
margin:0.5%;
padding:0.5%;
float:left;
background-color:yellow;
height: 50%;
}
#third {
width:32.333%;
float:left;
margin:0.5%;
background-color:blue;
}
#quarter {
width:23%;
margin:0.5%;
padding:0.5%;
float:left;
background-color:blue;
height:200px
}
</style>
<div id="page">
<div id="full">FULL</div>
<div id="half">
<h1>Half</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sodales urna non odio egestas tempor. Nunc vel vehicula ante. Etiam bibendum iaculis libero, eget molestie nisl pharetra in. In semper consequat est, eu porta velit mollis nec. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sodales urna non odio egestas tempor. Nunc vel vehicula ante. Etiam bibendum iaculis libero, eget molestie nisl pharetra in. In semper consequat est, eu porta velit mollis nec. Curabitur posuere enim eget turpis feugiat tempor. Etiam ullamcorper lorem dapibus velit suscipit ultrices. Proin in est sed erat facilisis pharetra.</div>
<div id="half">
<h1>Half</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sodales urna non odio egestas tempor. Nunc vel vehicula ante. Etiam bibendum iaculis libero, eget molestie nisl pharetra in. In semper consequat est, eu porta velit mollis nec. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sodales urna non odio egestas tempor. Nunc vel vehicula ante. Etiam bibendum iaculis libero, eget molestie nisl pharetra in. In semper consequat est, eu porta velit mollis nec. Curabitur posuere enim eget turpis feugiat tempor.</div>
<div id="third">Third</div>
<div id="third">Third</div>
<div id="third">Third</div>
<div id="quarter">Quarter</div>
<div id="quarter">Quarter</div>
<div id="quarter">Quarter</div>
<div id="quarter">Quarter</div>
<div id="row">
<div id="half">Half
<br>test</div>
<div id="quarter">Quarter</div>
<div id="quarter">Quarter</div>
</div>
I'm not sure how this would affect your intended styling overall, but assigning a fixed pixel height to your #half divs rather than a percentage will force them to be the same height.
#half {
width:48%;
margin:0.5%;
padding:0.5%;
float:left;
background-color:yellow;
height: 300px;
}
Update
I dug a little deeper and found that
"The percentage is calculated with respect to the height of the
generated box's containing block. If the height of the containing
block is not specified explicitly (i.e., it depends on content
height), and this element is not absolutely positioned, the value
computes to 'auto'. A percentage height on the root element is
relative to the initial containing block." Source
So basically, you have 2 options.
1) As I originally suggested, assign a fixed pixel height rather than a percentage.
2) Assign a fixed pixel height to the #page div. Your #half divs can now use percentages, which will measue based off of the #page div. For example:
#page {
width:95%;
text-align:center;
margin:auto;
height:1000px
}
#half {
width:48%;
margin:0.5%;
padding:0.5%;
float:left;
background-color:yellow;
height: 50%;
}
Will result in your #half divs being ~500px (not including margin and padding) 505px. The extra 5 pixels being the 0.5% padding that is also calculated from the #page height.