manipulate 3rd party *.less css without hacking it - css

In a Meteor (nodejs) project we use the less CSS preprocessor, and we use 3rd party "bootstrap-full.less" for our css styling.
There is one (maybe more) CSS rule in bootstrap that I would like to nuke, because it conditionally overrides other rules. (details below)
However, I don't want to "hack" the original bootstrap file, cause that is "vendor code".
I know I could re-override the CSS rules, but this is more work and hassle.
So the question is:
Is it possible to manipulate/process the parsed css rules in less before the actual css is generated?
In particular, there is this rule here,
#media (max-width: 767px) {
...
// Make all grid-sized elements block level again
[class*="span"],
.row-fluid [class*="span"] {
float: none;
display: block;
width: auto;
margin-left: 0;
}
which is undesirable in my case, because we only have this on a sidebar, that keeps the same width even on mobile. So it should continue to behave like a table with cells (span1, span2 etc) being floated.
Ok, maybe I will figure out a different solution for my CSS / bootstrap problem, but still it would be interesting to know if less allows me to manipulate the css it produces.

What I've done in my project is create a master .less file and within that file import my third party less files and then following that my custom files. Any classes that you want to update, create a dupe .less file with that class in it in your own directory and then simply edit the properties you want to change in your files. So for example:
master.less
#import "/static/bootstrap/less/bootstrap.less";
// My custom files
#import "scaffolding.less";
#import "type.less";
And then you have your own file called
type.less
h6{
color: #myCustomColor;
}
This way you keep all the bootstrap files intact and only overwrite what you need to. It also keeps the files nicely seperated so it's easy to navigate and also a snap if you ever need to update the bootstrap source.

Related

Rewriting CSS to SASS problem: same class definition in two css files

I've been assigned to rewrite an existing CSS code into SASS. This is my first experience with SASS, still a beginner.
So, first thing that I started with, I merged all css files into single file. Now I'm going through it and try to separate things into different .scss files.
I have layouted my SASS folder's architecture according to "7-1" pattern, which consists of 7 folders: abstracts, base, layout, modules, pages, themes and vendors. So far so good.
In process of separating my CSS into different files I came across a problem that I couldn't find answers to on google:
Say I have 2 CSS files - main.css and admin.css. There is defined a class in main.css:
.first-line {
padding-bottom:10px;
padding-left:30px;
padding-right:30px;
}
and a class with the same name is defined in admin.css
.first-line {
padding-left:15x;
padding-right:10px;
}
As I understood from SASS tutorials online (correct me if I'm wrong), SASS code should result in only one main.scss where I import all particles, modules etc. and it get's compiled to single main.css file. If so, how do I solve a problem like this, where I need a class to be defined differently only for a single page?
Try to nest that .first-line class in both the files (parent would be diff while nesting) ..... so while compiling into single file, it wont cause a problem
If it is a single-page application, that means you have JavaScript in use.
You can simply define a unique class for each page and assign this class to either body or html element (I prefer the latter one), and in run time you can simply set the page class dynamically. This way, you can define the first-line class and set the default values and put it into a shared .scss file and then overwrite the existing attributes or add new ones to that class for each individual page as needed.
E.g., you might want to structure it like this.:
pages/common.scss:
first-line {
padding-bottom:10px;
padding-left:30px;
padding-right:30px;
}
main.scss:
html {
import 'pages/common';
&.admin {
#import 'pages/admin';
}
&.other-page {
#import 'pages/other-page';
}
}

Remove border-radius from Bootstrap 4 breadcrumb - Sass

In Bootstrap 4 there is a Sass varaible called $enable-rounded which
"Enables predefined border-radius styles on various components."
(https://getbootstrap.com/docs/4.1/getting-started/theming/#sass-options)
I have a requirement to remove the rounded corners on the Breadcrumb component, but I don't want to remove it from any other components. Therefore I can't use $enable-rounded to do what I need.
However, I don't know what the optimal way to do this is.
The Sass for _breadcrumb.scss contains this:
.breadcrumb {
display: flex;
flex-wrap: wrap;
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
margin-bottom: $breadcrumb-margin-bottom;
list-style: none;
background-color: $breadcrumb-bg;
#include border-radius($border-radius);
}
How do I override #include border-radius($border-radius); without modifying _breadcrumb.scss?
All of the CSS for my app is condensed into 1 file (app.css) which is built from a Sass file (app.scss) which first includes the relevant Bootstrap 4 Sass files. So I could do something like this:
// app.scss
#import breadcrumb;
#import // other_bootstrap_sass_files
// CSS specific to my app
.breadcrumb {
border-radius: 0;
}
This seems a bit too similar to Bootstrap 3 where you had to override what you didn't want.
Is there a smarter way to do this with Sass for Bootstrap 4?
I think that for your specific case where you want only breadcrumbs without border-radius and all other components still have it, your only solution is doing like you mentioned in your question:
.breadcrumb {
border-radius: 0;
}
This seems a bit too similar to Bootstrap 3 where you had to override what you didn't want.
Personally I dont't see any other solution, only because you don't want to edit the original _breadcrumb.scss
If you look at the _variables.scss file, you can see all the variables that are set with !default - think of this as a preferences file. When the SCSS is compiled, your new values are swapped for the default values without having to overwrite the CSS.
Seems like $breadcrumb-border-radius: $border-radius !default; is what you want.
Two ways of resetting that value:
1) Make a copy of the _variables.scss file and place it in your project directory (I like changing the name to, say, _myvariables.scss ), look for that variable, remove the !default and change it to $breadcrumb-border-radius: 0;
OR
2) Make a file, say _myvariables.scss, that contains $breadcrumb-border-radius: 0; (and any other default values you want to change later on).
Next, import that new file BEFORE your bootstrap scss. In your example that would be your app.scss file:
// app.scss
#import myvariables.scss; //no underscore because it's a partial
#import // other_bootstrap_sass_files including the breadcrumb component
Now, when the SCSS is compiled, the breadcrumb radius will be set to 0 without changing anything else or overwriting css.

using Bootstrap and foundation together?

I am using twitter bootstrap for layout and css. But I like the foundation top bar navigation over what bootstrap provides. I tried to use the top bar code inside my html (built with bootstrap) and it messes up the layout. That is not surprising because both of them rely extensively on class named "row" and they have different properties.
One of the options I could think off is to override the row class some how in my style sheet but that would be too much of a work and doesn't seem right.
Other option might be using iframe.
Is there any other way this issue can be solved?
Ideally, you only need to use the top-bar CSS and JS code of Foundation, since that is the only component you mean to use. Here is the SCSS file (with dependancies on the variables declared in _settings.scss. Or you can use the generated CSS code.
If you still need to use .row, just copy the .row styling and name it different. I.e:
/* The Grid ---------------------- */
.foundation-row { width: 1000px; max-width: 100%; min-width: 768px; margin: 0 auto; }
Finally, dont't forget to include the jquery.foundation.topbar.js file and calling
$(document).foundationTopBar();
Old question but thought I'll share the latest if someone is looking for a seamless solution: Web Components
It's a bit of a more complex subject but will allow you to create widgets within completely isolated Shadow DOM's without overriding a thing. Read more about it
here and here. Then you'll be able to do something like this:
<template id="templateContent">
<style> #import "css/generalStyle.css"; </style>
</template>
Taken from this answer
Using an iframe for this is a bad idea. If you like the style for the Foundation top bar, just copy those styles into a custom class in your stylesheet.
Please note that you may have to override some of Bootstrap's default styles for the top bar to get it right.

Overriding External CSS

I have an external CSS file which is being imported into one of my pages. This external CSS assigns styles to HTML tags. For example,
table {
width: 100%;
font-size: 3em;
// long list of CSS styles
}
tr {
width: 100%;
font-size: 3em;
// long list of CSS styles
}
What is the best way to override these external CSS styles for a single table? For example, if I have a table and I don't want these external style on my table, how would I do that?
Thanks.
Edit - As a clarification, the "long list of CSS styles" has hundreds of styles. Most of the answers so far suggest that I override the provided CSS. Do I need to override all of the hundreds of styles?
Load your own CSS after the other CSS you want to override. The last read rules (if the same level of specificity) will win out. You only need to override the specific rules you need/want to -- not all of them.
you could use inline styles on your table,
<table style='width:90%'>
<tr style='font-size: 4.4em'>
or set up separate classes for the table in the external file, or create another .css file containing these styles
.otherTable{
width: 90%;
font-size: 2.3em;
// long list of CSS styles
}
and in your html,
<table class='otherTable'>
You should rewrite them to your needs right after the external css file.
Load them in this order:
http://www.externalserver.com/styles.css
css/general.css
And then apply your styles which will suit your website theme.
In addition to what j08691 stated, if you have issues with your CSS taking effect, add the phrase "!important" before the semicolon to ensure it overrides the other settings.
http://webdesign.about.com/od/css/f/blcssfaqimportn.htm
Be lazy and just scribble some javascript on that particular page.
Here is the SO Q/A on that:
https://stackoverflow.com/a/196038/1617149
Or you can do it in jQuery/Prototype before the page is rendered, e.g. on DOM load.

Is it possible to abstract out color theme definitions in CSS

We have many images which are actually picked up based on a color theme (e.g. blue, red, gray ...). We create files with a common name under each theme (e.g. background, ...), is there a way to define the color theme in a common place so that the definition can be abstracted out. This would prevent me from changing the color theme all over the css file.
body {
background: url('../img/blue/background.png');
font-size: 13px;
margin: 0px;
}
While the options suggested here are viable approaches, I'd like to mention SASS and LESS
They are two CSS extension languages, which amongst other things provide variables for doing this sort of color stuff you mention.
You can create dynamical CSS file by using any serverside scripting language like PHP.
style.css.php:
<?php
header("Content-type: text/css");
$theme = 'blue';
$color1 = '#fefefe';
?>
body {
background: url('../img/<?=$theme?>/background.png');
font-size: 13px;
margin: 0px;
}
.sometext {
color: <?=$color1?>
}
I don't believe you can with a pure css implementation as you would need to define your base paths for your images in a variable which you set with some logic (switch statement, if/else if, ..etc.) and then use that variable in the css.
Here are some options I thought of to do this. If you create a pseudo css file with your variable defined as a string that does not occur in css (ex: $basePath) and build out all your css rules in this fake css file as "$basePath+image.jpg". Then with some server side code retrieve the css file and create your template css files by replacing $basePath+ with the actual base path for that theme. The server side code would then save those css files as theme1.css, theme2.css, ...etc.
You then could use url variables to switch between themes using some server side code to insert a reference to the correct css theme file.
This way you would only need to maintain your pseudo template css file. Although you would need to rerun your css creation code each time you change the template css file so that your theme css files get updated.
Not natively in CSS - but you can write some scripts to compile your theme CSS files from templates with variable substitution. I would suggest having a 'layout' and a 'colour' css. The layout would be consistent irrespective of which theme the user is using. The colour css contains only those settings that change per theme.
<style type="text/css">
#import ulr(layout.css);
#import ulr(theme_<?= $activeTheme ?>_.css);
</style>
You could use a tool such as http://lesscss.org/ (if you like Ruby) to create your themed CSS files.
We use NAnt for something similar to this (not CSS, but same idea), and it saves a heap of time rather than maintaining multiple files that differ only by values.

Resources