Use parent div size for bootstrap responsive grid system - css

I need to use bootstrap 12 columns grid to get a responsive form based on the parent div's size.
As an exemple, whatever the size of the screen, the content need to see the div A's width and base the bootstrap's responsive design on that width.
My goal is to base my responsive design on the size of a modal window (in dhtmlx). If the user resize the modal window, the row should follow the rules (e.g. col-xs-12, col-sm-6, etc, but based on the size of the modal window, not the screen).
This fiddle show a modal window with some bootstrap form inside. I need the form to be responsive to the size of the modal form, not the screen size.
class="col-xs-12 col-sm-6"

As #makshh mentionned in the comment, it does not seem to be possible to do this right now. The only way I found is from another stack overflow question by #tsdexter:
$(document).ready(function(){
$('.somecontainer').on('resize',function(){
if ($('.somecontainer').width() < 640) {
$('.somecontainer').addClass('m');
} else {
$('.somecontainer').removeClass('m');
}
});
});

I just managed to make the grid system inside a modal act responsive to the modal's breakpoints in Bootstrap 4 with scss. Since the modal's max-width is responsive itself on some breakpoints, we need to generate new css on those breakpoints for that specific modal size (sm, md, lg, xl) which just overrules the Bootstrap's css media queries
Just copy/paste everything into a separate scss file, activate it and you are good to go
// This is a stripped version of the original "make-grid-columns" mixin from Bootstrap
#mixin make-modal-grid-columns($breakpoints) {
#each $breakpoint in map-keys($breakpoints) {
$infix: breakpoint-infix($breakpoint, $breakpoints);
#include media-breakpoint-up($breakpoint, $breakpoints) {
#for $i from 1 through $grid-columns {
.col#{$infix}-#{$i} {
#include make-col($i, $grid-columns);
}
}
}
}
}
$breakpoint-sm: 576px;
$breakpoint-lg: 992px;
$breakpoint-xl: 1200px;
.modal {
// Overrules all .col css inside .modal-sm to a single col
.modal-sm {
#include make-modal-grid-columns((
xs: 0
));
}
// modal-md (no specific class is also modal-md)
#include make-modal-grid-columns((
sm: $breakpoint-sm
));
.modal-lg {
#include make-modal-grid-columns((
md: $breakpoint-lg
));
}
.modal-xl {
#include make-modal-grid-columns((
md: $breakpoint-lg,
lg: $breakpoint-xl
));
}
}
FYI: it generates 350 lines of code

Related

Use calc function in CSS in JS in React component

I am working on one react component in which I need to use calc function in styles
const styles = {
spotImg:{
maxWidth:"100%",
maxHeight:"100%"
},
spotCont:{
width: /*here want to use calc with screen width*/
}
}
I want to use screen width with calc function in the above style code in react js component.
const styles = {
spotImg:{
maxWidth:"100%",
maxHeight:"100%"
},
spotCont:{
width: "calc(100vw)",
fallbacks:["-moz-calc(100vw)",
"-webkit-calc(100vw)",
"-o-calc(100vw)
]
}
}
Put the calc function in double quotations, and then you can use the CSS's vw to access screen width. Ie, 100vw provides you with the entire screen width. 100vw - 250px provides you with 250px less than the screen width, for example.
EDIT: Added fallbacks based on OP's comment about browser not accepting calc function.

Ionic 4 Modal Backdrop

I'm attempting to fix the way my modal works when presented.
When the screen size is large it has a translucent backdrop due to the min-height css. I don't mind that min height, I just want it all to be white.
It is created normally then presented:
this.modalCtrl.create({
component: AddCommentPage,
componentProps: { id: this.place.id }
}).then((element) => element.present());
Here is a view when the screen is large:
And when it is small (should be full screen):
I fixed it by adding the following code into my .scss file:
.modal-wrapper {
background-color: white;
}

If browser narrower than X, switch to mobile view?

For various reasons, I am creating a site (not online yet) that has separate pages for mobile. I want to add something to the "monitor" site which says "if the browser width is less than X pixels, view *mobilepagename.html instead of this page. What code can I add to the main site CSS to do this?
You can't switch pages with only CSS. You can do media queries to change styling based on screen size though.
#media screen and ( min-width: 'px' ) and ( max-width: 'px') {
/* Mobile Styles */
}
Or you can use
#media screen and ( max-width: 'px' ) {
/* Mobile Styles */
}
max-width and min-width don't need to be in pixels either. You can use a variety of units like vw, em, etc.
If you want to switch pages based on screen size you'll need to use Javascript.
if ( window.outerWidth < x ) {
window.location = 'newpage.html';
}
Edit
Combine the above Javascript with a resize event.
window.addEventListener('resize', function(e) {
if ( window.outerWidth < 1024 ) {
window.location = 'yourmobilepage.html';
}
});

Sass Grid System - Implementing gutters

I am trying to implement gutters for the following code(https://www.sassmeister.com/gist/eca78ee1435202c7e7dcaecc57c75bd5):
// ----
// Sass (vundefined)
// Compass (vundefined)
// dart-sass (v1.6.2)
// ----
//Variable Declarations
$__grid--columns:12;
$__grid--breakpoints: (
'xxxsmall': 375px,
'xxsmall': 480px,
'xsmall': 667px,
'small': 768px,
'medium': 960px,
'large': 1024px,
'xlarge': 1200px,
'xxlarge': 1400px,
'xxxlarge': 1600px,
);
$__grid--gutters: (
'small': 30px,
'medium': 30px,
'large': 30px
);
$__grid--cell-containers: (
'small': 1200px,
'medium': 1400px,
'large': 1600px,
'full': 100%
);
//Mixins for Grid
// #mixin createGutters() {
// .element {
// #if map-has-key($__grid--gutters, '') {
// content: 'Key Found';
// } #else {
// content: 'Key Not Found';
// }
// }
// }
#mixin createCells() {
#each $key, $value in $__grid--breakpoints {
#media screen and (min-width:$value){
#for $i from 1 through $__grid--columns {
&.#{$key}-#{$i}{
#if map-has-key($__grid--gutters, $key) {
margin-left:map-get($__grid--gutters, $key);
}
width:((100% / $__grid--columns) * $i);
}
}
}
}
}
//Spit out the cells
.row {
display:flex;
flex-wrap:wrap;
}
.cell {
// #include createGutters;
#include createCells;
}
//Styles not needed for grid
// * {
// box-sizing:border-box;
// }
// .color {
// padding:10px;
// background-color:salmon;
// }
As you can see I have a sass map for the gutters. I am trying to keep this as simple as possible. I'm not sure if I should be using an each loop, or a map-get() function, or maybe something else. I also want to have the margins on the left. I have to consider that if their are too many columns they will drop to the next line.
So basically if I set the margin of the first element to 0, and I have 4 columns that will fit within the container, the 5th item onward on will drop to the next line. The problem is that the margin on the 5th item will still be there.
This is a representation of what I mean:
item---item---item---item
---item---item---item---item
---item---item---item---item
So is there a way to:
Implement my sass map in a succinct way?
Add in support for if the items break to the next line for the margin
Better way to do this process? If so, feel free to fork the sassmeister code.
Your questions contains several points so I will try to answer them in an order that, think, will work better.
Normally purpose of the grid system (or columns system, to name it better to avoid names collision with CSS Grid specification) is to simplify elements positioning by providing ability for elements to take space of one or multiple "columns" defined by the grid. This definition means that columns can't wrap, so your flex-wrap: wrap breaks whole idea of columns system.
Your column width math width:((100% / $__grid--columns) * $i); does not include the fact that grid consists not just of columns, but also of gutters between them. Usually gutters are available only between columns so for 12-columns grid you need to have 11 gutters of defined size. It means that your actual math for grid column width should use calc() expression and it actual math will look like: width: calc(#{100% / $__grid--columns * $i} - #{$gutter-size / $__grid--columns * ($__grid--columns - $i)}); where $gutter-size is current gutter size. I've prepared a CodePen example to demonstrate this math.
If you want your grids to be even better - it is worth to let grid maths to be performed by dedicated library. Try to use Susy 3 for this purpose and your result will became much better.

Bourbon neat not behaving as expected in my mobile-first setup

I'm using bourbon neat for the first time and it's not behaving exactly how I would expect - which probably means I've set things up wrong.
I'm developing mobile-first, so I would expect my layout to remain the same between my desktop breakpoint and my larger breakpoint (for the styles to cascade to the next breakpoint). However, my layout jumps back to the mobile layout unless I redefine the styles again in the larger breakpoint.
Here is how I've defined my breakpoints in my base/_grid-settings.scss:
// Neat Overrides
$grid-columns: 4;
$max-width: 90%;
// Breakpoints
$first-breakpoint-value: 641px;
$second-breakpoint-value: 1024px;
$third-breakpoint-value: 1440px;
$fourth-breakpoint-value: 1920px;
$tablet: new-breakpoint(min-width em($first-breakpoint-value) max-width em($second-breakpoint-value) 8 );
$desktop: new-breakpoint(min-width em($second-breakpoint-value + 1) max-width em($third-breakpoint-value) 12 );
$large: new-breakpoint(min-width em($third-breakpoint-value + 1) max-width em($fourth-breakpoint-value) 12 );
$xlarge: new-breakpoint(min-width em($fourth-breakpoint-value +1) 12 );
Then my element looks like this:
.container {
#include outer-container;
.swatch {
// mobile styles (here my swatch has a width of 100%)
border: 1px solid #000;
text-align: center;
margin-bottom: $gutter;
//MEDIA QUERIES
#include media($tablet) {
#include span-columns(4);
#include omega(2n);
}
#include media($desktop) {
#include span-columns(3);
#include omega(4n);
padding: 2em -0px;
}
#include media($large) { }
#include media($xlarge) { }
}
}
Now I was expecting the styles from my $desktop media query to cascade all the way up to the $xlarge media query, however currently the .swatch element jumps back to being 100% of it's parent container at the $large and $xlarge breakpoints.
What have I done wrong?
I shouldn't need to keep repeating the same code for every breakpoint if I want the styles to cascade up.
You are defining a media query range, which is why it is snapping back to the mobile view in between.
Remove the max value from your breakpoint and the values will cascade up to desktop.
Im not too familiar with neat but the following should work:
$tablet: new-breakpoint(min-width em($first-breakpoint-value) max-width em($second-breakpoint-value) 8 );
becomes:
$tablet: new-breakpoint(min-width em($first-breakpoint-value) 8);
Hope this helps you or any one else reading this post, I had a similar issue and found this handy omega reset mixin.
http://www.joshfry.me/blog/2013/05/13/omega-reset-for-bourbon-neat
Thanks #nickspiel - that was half the answer! You are correct, adding min-with only breakpoints is the way to get the styles to cascade up the breakpoints. Doing that with Bourbon Neat and an element that is using omega is a bit more tricky.
It seems that I have 2 choices:
Use media query splitting, as per the docs, but then you need to set styles for every breakpoint.
Use your suggestion of min-width breakpoints in conjunction with an Omega reset - I'm going with this option.

Resources