Leaving aside the question of whether you should serve single or multiple stylesheets, assuming you're sending just one, what do you think of this as a basic structure?
/* Structure */
Any template layout stuff should be put into here, so header, footer, body etc.
/* Structure End */
/* Common Components*/
Repeated elements, such as signup forms, lists, etc.
/* Common Components End*/
/* Specific Page 1 */
Some pages might have specific styles, that would go here.
/* Specific Page 1 End */
/* Specific Page 2 */
As above
/* Specific Page 2 End */
/* Specific Page etc */
And so on.
/* Specific Page etc End */
That's similar to how I structure mine, however, I find that using sub-headings is the best way to do it, so I use this structure:
/*************************
* GLOBAL *
*************************/
/* All of the common stuff goes here under the appropriate sub headings */
/* Heading formatting */
/* Text formatting */
/* Form formatting */
/* Table formatting */
/* etc */
/*************************
* LAYOUT *
*************************/
/* All the layout things go here under sub-headings */
/* Header */
/* Left Sidebar */
/* Right Sidebar */
/* Footer */
/*************************
* NAVIGATION *
*************************/
/* I put navigation separate to the layout as there can be a number of navigation points under their sub-headings */
/* Main (horizontal) Navigation */
/* Left Navigation */
/* Right Navigation */
/* Breadcrumb Navigation */
/*************************
* FORMS *
*************************/
/* Any form formatting that varies from the common formatting, if there are multiple differently formatted forms, then use sub-headings */
/*************************
* TABLES *
*************************/
/* Same deal as forms */
/*************************
* LISTS *
*************************/
/* Same deal as forms and tables */
/*************************
* CONTENT *
*************************/
/* Any specific formatting for particular pages, grouped by sub-headings for the page the same way as forms, tables and lists */
/*************************
* CSS SUPPORT *
*************************/
/* This is for any special formatting that can be applied to any element on any page and have it override the regular formatting for that item. For example, this might have things like: */
.float-right { float: right; }
.float-left { float: left; }
.float-center { margin-left: auto; margin-right: auto; }
.clear { clear: both }
.clear-block { display: block }
.text-left { text-align: left }
.text-right { text-align: right }
.text-center { text-align: center }
.text-justify { text-align: justify }
.bold { font-weight: bold }
.italic { font-style: italic }
.underline { border-bottom: 1px solid }
.nopadding { padding: 0 }
.nobullet { list-style: none; list-style-image: none }
/* etc */
Hope that helps.
I generally don't recommend writing on a single line like that though, or like suggested in the link Adam posted, they get very difficult to skim over if they get long. For the examples above, it was just quicker to type them that way so I didn't have to indent every line.
For formatting I would recommend this structure:
.class {
width: 200px;
height: 200px;
border: 1px solid #000000;
}
And so on, I put the structure of the class or ID at the top, then any other formatting, like the font etc below that. Makes it very quick and clear to skim over.
Whatever makes sense to you is good enough. Frankly, when someone else comes looking for something in your stylesheet - or when you come looking for something, for that matter - they're not going to try to figure out what your organizing structure was. They're just going to search for whatever class or element they need to see. So as long as you generally keep stuff that's related together, and section things off with comments like #Matt suggests, you're fine.
The fact of the matter is that even with a very well-thought-out organizational structure - just like with a well-thought-out filing system - it's not always obvious what goes where; so you're better off just being somewhat sensible, not devoting a lot of time to keeping things organized, and relying on search tools to find what you need.
I organize my CSS in a similar way as yours but I do start with a reset section. The main idea is to go from general to specific. So here it goes:
reset
structure
html_tags
navigation
specific sections
Error messages - that's my last section
The structure you presented is exactly what I use. However, it seems to me that it still got too complex with new rules showing up and overriding each other... Perhaps I should try to stick to the solution suggested in the topic linked to by Adam instead.
It seems like every time I create a new css file, I find a new way to organize it. And they are ALL better than the previous.
Related
hope one of you can give me a “how to” hint.
I’m a newbie here and in building a website. I’ve written a website with “50 odd pages” for my photos. Photography is my passion, not website building. On each page 1 photo, is centered vertically, horizontally, bladibla, and a button for showing a full-screen copy of the photo. For that purpose, I use CSS overlay and a script to open and close.
As you’ll understand, on each page the same CSS stylesheet, except for the URL of the photo which is mentioned twice. In the head as part of the CSS overlay code and once more in the body for addressing the photo.
A snippet of the overlay code:
.overlay-content {
background-image: url("https://.../images/photo_0X.png");
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
And in the body:
<img id="photo" src="https://.../images/photo_0X.png">
This works perfectly but for maintenance purposes, I would like to simplify the code of my pages and therefore create 1 (external) CSS file for all pages. Regularly I change background color, and fonts, and add pages/photos.
My question is as follows: Is it possible to generalize the “background-image: url” line of the overlay code? E.g. by adding an image id to the image line in the body. There’s just 1 photo on each page so I could give every photo the same img id. E.g. img id=”photo”. As above. In other words; would it be possible to refer in the overlay code to the image id in the body instead of repeating the full path to the photo? Referring to the image id is just an idea, every other suggestion is appreciated. P.S. I love simple solutions.
Thanks a lot, even if it’s just for reading this “long read” (-;
example here: https://jsfiddle.net/9sx3bjg7/
there isn't any need to create 50 pages by hand.
just create an array with all your images ["./myImg", "./anotherImg", "https://myImageLink"]
and create one HTML file
and change the URL parameter with the index of the image,
then get the index from the link and show the image on the index of the array
in javascript we change the --src CSS variable, and everything will work!
css var: https://developer.mozilla.org/en-US/docs/Web/CSS/var
why change the URL?
so if the user like an image
he can copy the link,
and maybe send it to another friend,
and the friend can see directly the image
without the need to see all the images first.
this means every time you click next (➡️) you refresh the page and have a new image (and now you solved the problem of more pages)
for example:
localhost:3000/?id=10
myUrl.com/?id=10
this technique is used also by google.com,
try for example do a search,
and the link will be changed to ?q=.
same concept also here for not making infinite pages.
how it work?
here the working example:
/* get img container */
let img = document.querySelector("#img-container");
/* get id from url */
/* if the user see the website for first time reset to 0 */
let id = getId();
changeImg();
/* button functionalities */
function next() {
id++;
window.location.search = `id=${id}`;
}
function prev() {
id--;
window.location.search = `id=${id}`;
}
/* id functionalities */
function getId() {
let result = []; // []
// details about location.search https://stackoverflow.com/a/26803253/17716837
let stringArray = location.search.replace("?", "").split("&"); // ["id=number", "another=string"]
stringArray.forEach((string) => {
result.push(string.split("="));
}); // [[id, number], [other, string], [another, string]
result = Object.fromEntries(result); // {id: number, another: string}
return result.id ?? 0; // number (or 0 if undefined)
}
function resetId() {
window.location.search = `id=0`;
}
/* change image functionalities */
function changeImg() {
/* if the user see all image, then we reset the id to 0 */
let choosedImg = imgArray[id] ? imgArray[id] : resetId();
/* changing a css variable */
img.style.setProperty("--src", `url(${choosedImg})`);
}
/* the most important part is here, the other also only css designs */
#container #img-container {
/* src get changed automatically by javascript */
background-image: var(--src);
background-position: center;
background-repeat: no-repeat;
background-size: cover;
border-radius: 0.5rem;
}
* {
box-sizing: border-box;
}
body {
/* centering vertically and horizontally */
display: grid;
place-items: center;
height: 100vh;
margin: 0;
}
/* container responsive */
#container {
width: 80vmin;
height: 80vmin;
}
#container {
padding: 1rem;
border-radius: 0.5rem;
border: 1px solid #ccc;
}
#container {
/* make image bigger, buttons smaller */
display: grid;
grid-template-rows: 1fr auto;
gap: 1rem;
}
/* button flexbox */
#btn-container {
display: flex;
gap: 1rem;
}
/* buttons responsive width */
#btn-container button {
flex: 1;
}
<div id="container">
<div id="img-container" style="--src: https://picsum.photos/500">
<!-- here it will be a image -->
</div>
<div id="btn-container">
<button title="previus" onclick="prev();">⬅️</button>
<button title="next" onclick="next()">➡️</button>
</div>
</div>
<!-- just change the array :) -->
<script>
/* here put all your img urls */
let imgArray = [
"https://i.stack.imgur.com/ZtQFV.jpg", /* 0 */
"https://i.stack.imgur.com/1zsuD.jpg", /* 1 */
"https://i.stack.imgur.com/gONSm.jpg", /* 2 */
"https://i.stack.imgur.com/pmIwb.jpg", /* 3 */
"https://i.stack.imgur.com/7qow3.jpg", /* 4 */
"https://i.stack.imgur.com/JPr4x.jpg", /* ... until 50+ */
];
</script>
<!-- make sure to import the script at the end, or after the array in html -->
<script src="script.js"></script>
responsive:
also is responsive because we using vmin
vmin means CSS will get the smaller dimension on screen (height or width) and then divide it by 100.
vertically responsive:
horizontally responsive:
I want to create a component and expose certain properties that could be overridden by parent elements.
Here's an example. Let's say I'm creating a button which has its own colors, but allows to change its background color if there's a --button-bg-color defined:
.my-button {
--bg-color: blue;
/* lots of other css... */
/**
* here I assume that there might be a --button-bg-color defined,
* but I have a fallback to my own --bg-color variable
*/
background-color: var(--button-bg-color, var(--bg-color));
}
The problem with the code above is that the --button-bg-color variable is referenced somewhere deep down the styling.
What I wish I could do is the declare somewhere up top that I might want to use this variable. This would tell me that this component expects to be overridden.
Maybe something like this?
.my-button {
--button-bg-color: undefined; /* is there something like undefined? */
--bg-color: blue;
/* the rest of the code is the same */
}
Oh well, I just realized that we can do this:
.my-button {
--bg-color: var(--button-bg-color, blue); /* inherit with fallback */
/* lots of other css... */
background-color: var(--bg-color);
}
This way there's also less repetition.
I currently am styling my social sharing buttons using groupings (all Facebook buttons have a set style, all Twitter buttons do, etc.). Currently, I achieve this using a massive grouping of YUI's for each button type - this makes creating new sharing buttons extremely tedious, as I have to inspect each button to find its ID. Below is the code that stylizes my Facebook share buttons. The format is identical for my other button types, just with different YUIs - woefully lengthy. However, my code is functional as is:
#block-yui_3_17_2_1_1486492076694_136568, #block-yui_3_17_2_1_1486492076694_229456, #block-yui_3_17_2_1_1486492076694_301518, #block-yui_3_17_2_1_1486492076694_346464, #block-yui_3_17_2_1_1486492076694_390386, #block-yui_3_17_2_1_1486497764071_38998, #block-yui_3_17_2_1_1486497764071_84939, #block-yui_3_17_2_1_1486497764071_127888, #block-yui_3_17_2_1_1486497764071_167750, #block-yui_3_17_2_1_1486497764071_210706, #block-yui_3_17_2_1_1486762828716_16671, #block-yui_3_17_2_1_1487613145787_165402, #block-yui_3_17_2_1_1488578082993_168899, #block-yui_3_17_2_1_1489175439402_256947, #block-yui_3_17_2_1_1489873739917_158023, #block-yui_3_17_2_1_1490053051323_201623, #block-yui_3_17_2_1_1490837162453_152647, #block-yui_3_17_2_1_1491429139219_249912, #block-yui_3_17_2_1_1491948942477_176351 {
display: inline-block;
padding-bottom: 0;
padding-top: 0;
}
Ideally, I'd like to target each button type using their respective classes to REALLY consolidate the amount of code I have written (and make future additions much more efficient). I've tried everything I could think of, but nothing seems to work.
I'm currently working on the Squarespace platform.
Your problem might be because of Squarespace's default styles. When targeting elements, CSS prefers the more precise selector:
.social-icon {
background-color: red;
/* Less preferred */
}
html body div.social-area img.social-icon {
background-color: blue;
/* More preferred */
}
You can override this by using !important:
.social-icon {
background-color: red !important;
/* More preferred */
}
html body div.social-area img.social-icon {
background-color: blue;
/* Less preferred */
}
so when you style your social icons, use !important to override Squarespace's default styles.
.social-icon {
display: inline-block !important;
padding-bottom: 0 !important;
padding-top: 0 !important;
}
Hope this helps!
Having a bit of an issue with a Drupal site. If you take a look here and look down at the facebook block, it's overlapping the blocks above it, the twitter one is not doing this. I have tried various changes in Drupal but nothing has changed. Anyone have any idea how to make it line up with the twitter one?
It is the two margin top properties asigned to the .block-facebook-wall. Disable those.
.block-facebook-wall {
/* margin-top: -7.36714em; */
}
media (min-width: 38em){
.block-facebook-wall {
width: 48.93617%;
clear: right;
float: right;
margin-right: 0;
/* margin-top: -6.8541em; */
}
}
I use Web Essentials 2012 in VS 2012.
When I compile LESS file with content like that:
/* HEADER */
.header{
background: red;
}
/* FOOTER */
.footer{
background: black;
}
...to CSS file, the outcome is this:
/* HEADER */
.header{
background: red;
}
/* FOOTER */
.footer{
background: black;
}
Is there an option "Keep original formatting" or set of option with which I could keep the original formatting ?
Sort of...
If your main desire is to keep the "gap" between the comment and the style for easier visual recognition, then in most cases this should work (unless perhaps you minify the code), because within the comment it will preserve the formatting of the empty lines down to the new position of the end comment marker */:
/* FOOTER *
*/
.footer{
background: black;
}
That's about as close as you can get. Note: I have not actually tested this with Web Essentials, just on the less2css.org compiler.