How to Customize Bootstrap Column Widths? - css

I have this, but I feel 4 is too big for my sidebar width and 3 is too small (it has to add up to 12).
<div class="col-md-8">
<div class="col-md-4">
I tried this but it doesn't work:
<div class="col-md-8.5">
<div class="col-md-3.5">
Is there another way to get a similar outcome?
Thanks for your help!

To expand on #isherwood's answer, here is the complete code for creating custom -sm- widths in Bootstrap 3.3
In general you want to search for an existing column width (say col-sm-3) and copy over all the styles that apply to it, including generic ones, over to your custom stylesheet where you define new column widths.
.col-sm-3half, .col-sm-8half {
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
#media (min-width: 768px) {
.col-sm-3half, .col-sm-8half {
float: left;
}
.col-sm-3half {
width: 29.16666667%;
}
.col-sm-8half {
width: 70.83333333%;
}
}

For a 12 columns grid, if you want to add half of a column (4,16667%) to each column width. This is what you do.
For example, for col-md-X, define .col-md-X-5 with the following values.
.col-md-1-5 { width: 12,5%; } // = 8,3333 + 4,16667
.col-md-2-5 { width: 20,83333%; } // = 16,6666 + 4,16667
.col-md-3-5 { width: 29,16667%; } // = 25 + 4,16667
.col-md-4-5 { width: 37,5%; } // = 33,3333 + 4,16667
.col-md-5-5 { width: 45,83333%; } // = 41,6667 + 4,16667
.col-md-6-5 { width: 54,16667%; } // = 50 + 4,16667
.col-md-7-5 { width: 62,5%; } // = 58,3333 + 4,16667
.col-md-8-5 { width: 70,83333%; } // = 66,6666 + 4,16667
.col-md-9-5 { width: 79,16667%; } // = 75 + 4,16667
.col-md-10-5 { width: 87,5%; } // = 83,3333 + 4,16667
.col-md-11-5 { width: 95,8333%; } // = 91,6666 + 4,16667
I rounded certain values.
Secondly, to avoid copying css code from the original col-md-X, use them in the class declaration. Be careful that they should be added before your modified ones. That way, only the width gets override.
<div class="col-md-2 col-md-2-5">...</div>
<div class="col-md-5">...</div>
<div class="col-md-4 col-md-4-5">...</div>
Finally, don't forget that the total should not exceed 12 columns, which total 100%.
I hope it helps!

You could certainly create your own classes:
.col-md-3point5 {width: 28.75%}
.col-md-8point5 {width: 81.25%;}
I'd do this before I'd mess with the default columns. You may want to use those inside these.
You'd probably also want to put those inside a media query statement so that they only apply for larger-than-mobile screen sizes.

Bootstrap 4.1+ version of Antoni's answer:
The Bootstrap mixin is now #include make-col($size, $columns: $grid-columns)
.col-md-8half {
#include make-col-ready();
#include media-breakpoint-up(md) {
#include make-col(8.5);
}
}
.col-md-3half {
#include make-col-ready();
#include media-breakpoint-up(md) {
#include make-col(3.5);
}
}
Source:
Official documentation
Bootstrap 4 Sass Mixins [Cheat sheet with examples]

You can use Bootstrap's own column mixins make-xx-column():
.col-md-8half {
.make-md-column(8.5);
}
.col-md-3half {
.make-md-column(3.5);
}

you can customize bootstrap stylesheet, as in:
.col-md-8{
width: /*as you wish*/;
}
Then, set the media query for that too, as in:
#media screen and (max-width:768px){
.col-md-8{
width:99%;
}
}

Related

mixins overwriting media queried style

I have some JS functionality that changes the css class on my body element. Based on a click, i will change the css class of my body element to one of the following: .font-default, .font-medium, and .font-large.
I have the following mixins that determines the font size of an element based on the body element's class. That looks like this:
#function rem-calc($size) {
$remSize: $size / 16;
#return #{$remSize}rem;
}
#mixin font-size($size) {
#if $size >= 20 {
font-size: rem-calc($size);
} #else if $size == 18 {
font-size: rem-calc(18);
.font-large & {
font-size: rem-calc(20);
}
} #else {
font-size: rem-calc($size);
.font-medium & {
font-size: rem-calc($size + 2);
}
.font-large & {
font-size: rem-calc($size + 4);
}
}
}
An example of me using this mixin is as follows:
.content {
#include font-size(16);
#media (min-width: 1024px) {
#include font-size(30);
}
}
Here's is the corresponding html and css on the linked codepen at the bottom:
<body class="body">
<div class="content">Content</div>
<button class="button">
click to add
</button>
</body>
<script>
const button = document.querySelector('.button')
button.addEventListener('click', () => {
console.log(document.querySelector('.body'))
document.querySelector('.body').classList.add('font-medium');
})
</script>
According to my ruleset (the mixin), in the desktop version, font-size should remain unchanged since size >= 20. However in practice, when I click the button that changes the class to medium, it uses the "mobile" version of the style and overwrites the style that's placed in the media query.
Is there anyway regarding specificity such that I can still use this mixin so that the mobile styles don't bleed into the styles nested in the media queries?
If not, what might be a different solution to this problem?
Here's a pen that shows the issue. When clicking the button, I want the font to remain unchanged. https://codepen.io/rv-akim/pen/WVJpWj
You can clearly see that .font-medium .content is overriding .content due to the fact the former is more specific even though .content is inside of a media query.
Update your code so your normal state of the font size uses a class
#mixin font-size($size) {
#if $size >= 20 {
.normal & {
font-size: rem-calc($size);
}
} #else if $size == 18 {
.normal & {
font-size: rem-calc(18);
}
.font-large & {
font-size: rem-calc(20);
}
} #else {
.normal & {
font-size: rem-calc($size);
}
.font-medium & {
font-size: rem-calc($size + 2);
}
.font-large & {
font-size: rem-calc($size + 4);
}
}
}
.content {
#include font-size(16);
#media (min-width: 1024px) {
#include font-size(30);
}
}
Add class normal to your body tag
<body class="body normal">
Basically, where you only declared the font size rule, I wrapped it with .normal & {}
If you learn to use the Inspector, it will save you tons of headaches later

Sass flex order does nothing on generated elements

I have a couple of SVG that get rendered like this
export const MenuHeaderTab = (props: RenderableProps<Props>) =>
{
const css = props.isActive ? "menu-tab menu-tab-selected" : "menu-tab";
return (
<div onClick={() => props.onClick()} className={css}>
{props.children}
</div>
)
}
the problem i have is that in desktop mode it works fine cause they render in the order that i want them to. the problem is that in mobile portrait mode i want one of the rendered SVG to be first in the order (row). So i thought i use row and just set the className on the SVG
so here is the sass/css
#media all and (orientation: portrait)
{
.menu-tab {
width: 10%;
height: 20%;
margin-left: 4vw;
}
.menu-close-button {
order: -1;
}
.menu-leaderboard-button {
order: 2;
}
.menu-prize-button {
order: 3;
}
.menu-rules-button {
order: 4;
}
so i even provided order to all the SVG and -1 to the one that should be first, but they all stay in the exact same order still. Anyone have any clue why this happens.
Order attribute only works if the father element use display: flex
Assuming the .menu-tab is the father's div of this elements .menu-close-button, .menu-leaderboard-button, .menu-prize-button, .menu-rules-button, you just need to set a display: flex to the .menu-tab
Bellow follow an example of the code:
Look athe the close button, its the last element but how its set -1 as order, it become the first element
.menu-tab {
width: 10%;
height: 20%;
margin-left: 4vw;
display: flex;
}
.menu-tab a{
margin-right: 10px;
}
.menu-close-button {
order: -1;
}
.menu-leaderboard-button {
order: 2;
}
.menu-prize-button {
order: 3;
}
.menu-rules-button {
order: 4;
}
<div class="menu-tab">
leaderboard
Prize
Rules
Close
</div>

Using SASS's #for for multiple selectors and 1 body [duplicate]

I'm working with the SCSS syntax of SASS to create a dynamic grid system but I've hit a snag.
I'm trying to make the grid system completely dynamic like this:
$columns: 12;
then I create the columns like this:
#mixin col-x {
#for $i from 1 through $columns {
.col-#{$i} { width: $column-size * $i; }
}
}
Which outputs:
.col-1 {
width: 4.16667%;
}
.col-2 {
width: 8.33333%;
}
etc...
This works well but what I want to do next is dynamically generate a long list of column classes separated by commas based on the number of $columns chosen - e.g I want it to look like this:
.col-1,
.col-2,
.col-3,
.col-4,
etc... {
float: left;
}
I've tired this:
#mixin col-x-list {
#for $i from 1 through $columns - 1 {
.col-#{$i}-m { float: left; }
}
}
but the output is this:
.col-1 {
float: left;
}
.col-2 {
float: left;
}
etc...
I'm a little stuck on the logic here as well as the SCSS syntax required to create something like this.
Does anyone have any ideas?
I think you may want to take a look at #extend. If you set that up something like:
$columns: 12;
%float-styles {
float: left;
}
#mixin col-x-list {
#for $i from 1 through $columns {
.col-#{$i}-m { #extend %float-styles; }
}
}
#include col-x-list;
It should render in your css file as:
.col-1-m, .col-2-m, .col-3-m, .col-4-m, .col-5-m, .col-6-m, .col-7-m, .col-8-m, .col-9-m, .col-10-m, .col-11-m, .col-12-m {
float: left;
}
#extend in the docs.
There's also a way to do what your question is specifically asking for: generate (and use) a list of classes with commas separating them. D.Alexander's response totally works in your situation, but I'm posting this alternative in case there's another use case for someone looking at this question.
Here's a Pen demonstrating: http://codepen.io/davidtheclark/pen/cvrxq
Basically, you can use Sass functions to achieve what you want. Specifically, I'm using append to add classes to my list, separated by commas, and unquote to avoid compilation conflicts with the period in the classnames.
So my mixin ends up looking like this:
#mixin col-x {
$col-list: null;
#for $i from 1 through $columns {
.col-#{$i} {
width: $column-size * $i;
}
$col-list: append($col-list, unquote(".col-#{$i}"), comma);
}
#{$col-list} {
float: left;
}
}
thnx to #davidtheclark here is a more generic version:
#mixin attr-x($attr, $attr-count: 10, $attr-steps: 10, $unit: '%') {
$attr-list: null;
#for $i from 1 through $attr-count {
$attr-value: $attr-steps * $i;
.#{$attr}#{$attr-value} {
#{$attr}: #{$attr-value}#{$unit};
}
$attr-list: append($attr-list, unquote(".#{$attr}-#{$attr-value}"), comma);
}
#{$attr-list} {
//append style to all classes
}
}
Use it like this:
#include attr-x('margin-left', 6, 5, 'px');
//or
#include attr-x('width');
The result looks like this:
.margin-left5 {
margin-left: 5px; }
.margin-left10 {
margin-left: 10px; }
...
.margin-left30 {
margin-left: 30px; }
.width10 {
width: 10%; }
.width20 {
width: 20%; }
...
.width100 {
width: 100%; }

changing css class variables

I am looking at less.js, mixin looks like the way touching the variable in css but i am not sure if my problem is solvable using less.js.
I want to make some class with parameter, e.g. with the format
marginTop-10 or marginTop(15)
10,15 are some numbers which i can change to specify the margin top pixel, basically these numbers can be any number.and i will use these class in my paragraph class such as
<p class="marginTop(some number)">css help</p>
How can i make this happen?
You should first write your Less file, for instance as follows:
.marginTop(#topMargin) {
margin-top: #topMargin;
}
p.marginTop-10 {
.marginTop(10px);
}
p.marginTop-15 {
.marginTop(15px);
}
The preceding Less code will compile into the following CSS code:
p.marginTop-10 {
margin-top: 10px;
}
p.marginTop-15 {
margin-top: 15px;
}
After that you can use in your HTML:
<p class="marginTop-10">css help</p>
<p class="marginTop-15">css help</p>
Notice that you can also compile a list of classes dynamically, see also: LESS loops used to generate column classes in twitter - How do they work?
Doing that you could write the the following Less code:
#margins: 10 20 50;
.marginTop(#i: 1) when (#i <= length(#margins)) {
.marginTop(#i + 1);
#margin-top: extract(#margins,#i);
.marginTop-#{margin-top} {
margin-top:unit(#margin-top,px);
}
}
.marginTop();
outputs:
.marginTop-50 {
margin-top: 50px;
}
.marginTop-20 {
margin-top: 20px;
}
.marginTop-10 {
margin-top: 10px;
}

Declare variable conditionally in LESS css

I currently have two Views that are using the same layout. However, they differ from each other in the following aspect:
View Foo:
<div class="MajorSection" id="foo">
</div>
View Bar:
<div class="MajorSection" id="bar">
</div>
And I want to declare #labelWidth differently between these two classes in one .less file so that I don't need to repeat myself with the following code.
.MajorSection {
#labelWidth: 10em;
.editor-label {
width: #labelWidth;
}
input, textarea {
width: (#editorWidth)-(.5em); //border & padding
}
}
In View Foo I want #labelWidth to be 10em, and in Bar I want it to be 20em. Is there anyway to do that?
I think the simplest method to achieve this is to define "depended" styles via parametric mixin, e.g.:
.MajorSection {
#foo& {
.labelStyles(10em);
}
#bar& {
.labelStyles(20em);
}
.labelStyles(#width) {
.editor-label {
width: #width;
}
}
input, textarea {
width: (#editorWidth - .5em); // border & padding
}
}
CSS output:
#foo.MajorSection .editor-label {
width: 10em;
}
#bar.MajorSection .editor-label {
width: 20em;
}
.MajorSection input,
.MajorSection textarea {
width: ...;
}

Resources