This is the markup of a web page I'm working on right now:
<section style="background-image: url(img/about-banner.jpg); height: 100vh; position: relative; background-size: cover;">
<div class="container" style="width: 90%;">
<div class="display-table">
<div class="table-cell" style="vertical-align: bottom;">
<div class="content about-header" style="margin-bottom: 20vh; margin-left: -2vw;">
<h1 class="text-white other-header-h1" style="font-size: 3.5vw;">Title Text</h1>
</div>
</div>
</div>
</div>
</section>
The two main areas of interest are
<div class="content about-header" style="margin-bottom: 20vh; margin-left: -2vw;"
and
<h1 class="text-white other-header-h1" style="font-size: 3.5vw;">Title Text
For screen sizes below 1025x I'm trying to make the font-size 5vw and margin-bottom: 30vh;
These are the media queries I put in responsive.css:
#media (max-width: 1024px) {
.header_section_fix {
font-size: 1.5vw;
}
.header_fix_links a {
margin-right: 3%;
}
.about-header {
margin-bottom: 30vh;
margin-left: -2vw;
}
.other-header-h1 {
font-size: 5vw;
}
In the above css, both .header_section_fix and .header_fix_links are working.
However the media queries for .about-header and .other-header-h1 do not work on the webpage.
Below are a few ways to isolate this issue for the fix:
Firstly get rid of all your inline styles, and put them in the external style-sheet. Your going to have a hard time getting your media queries to override inline styles.
Secondly, double check that your meta view-port is being defined properly in the head of your document.
Thirdly make sure there is no conflicts with these selectors and styles being defined elsewhere in the application. ie. If you are defining margin-top: with a selector somewhere else, then use margin-bottom: in your media queries; stuff like that (make sure you are consistent with css properties and not creating conflicts).
Fourthly, make sure your CSS is valid and there is no syntax errors. Also, try to match the order of the CSS selectors in the stylesheet with how they appear in the HTML.
Your last resort scenarios would be using !important; or enclosing in a separate, second media query instance; or rearranging where these selectors are being called in the stylesheet. These may work, but ultimately would be a reach around for some conflict.
Normal specificity rules apply.
The inline style has a higher specificity than the ruleset in the media query, so it overrides the value you want.
Move the value in the style attribute into the stylesheet.
Related
I'm using a CMS with predefined classes (cbFormFieldCell).
So I can't change some class elements because they are used at some other parts of the website. If I change the format for every element of that class the website is broken.
I want to change the style of the class "cbFormFieldCell" only inside a <table class="tabelle">. Outside the table the other elements may not be changed.
.cbFormFieldCell { min-width: 300px; max-width: 300px; overflow: hidden;}
That works for every class of the website. But some objects are broken.
Is it possible to do something like that:
Change only predefined class="cbFormFieldCell" elements in table class="tabelle"?
e.g.
.tabelle.cbFormFieldCell
{ min-width: 300px; max-width: 300px; overflow: hidden; }
Can anyone help?
The 'space' between your CSS classes are used to target different elements. Below you will find an example what happens when you combine classes without or with spaces.
Hopefully this help you to understand how to target your element.
.parent-1 .child {
color: green;
}
.parent-2.child {
color: red;
}
/* addition styling */
p {
padding: 20px;
background-color: #eff0f1;
border-radius: 10px;
}
<!-- Without container -->
<p class="child">No CSS rules are applied here.</p>
<!-- With containers -->
<div class="parent-1">
<p class="child">This will be targeted: green</p>
</div>
<div class="parent-2">
<p class="child">No CSS rules are applied here.</p>
</div>
<div class="parent-2 child">
<p class="child">This will be targeted: red</p>
</div>
You can use css !important like this
.cbFormFieldCell { min-width: 300px !important; max-width: 300px !important; overflow: hidden !important;}
"!important" makes css attribute to be first-level
You are concatenating the classes by writing them with no space, which basically means
.tabelle.cbFormFieldCell will apply to an element that has BOTH those classes.
In order to target .cbFormFieldCell inside of .tabelle add a space between them like this .tabelle .cbFormFieldCell.
Or if it's a direct child of .tabelle, you can use the descendant selector like this .tabelle > .cbFormFieldCell
Thank you everyone!
I actually had to remove the space, use important and additionally use another default class.
.cbFormTableEvenRow .cbFormFieldCell
{ min-width: 100px !important; max-width: 100px !important; width: 100px !important; overflow: hidden !important; }
The answer to this question is not pointing out some css selector or property that I am unaware of. It is also not throwing together some random css that makes this specific case work. Off the top of my head I can think of several ways to make this specific example work. I'm sure there are hundreds more.
What are the best practices for creating CSS such that various design elements are decoupled?
Explanation of what I mean:
I am a computer programmer with an ok design sense. When writing good code I look to create classes/objects that are decoupled, meaning there are not strange and unexpected interactions between them. I can mix and match my classes/objects freely and the results work well and are what you would expect. All my attempts to learn/create CSS best practises don't work out this well. I've been a .NET web developer for 10+ years now. For a long time I believed in semantic CSS. I loved csszengarden.com. I've tried to learn OOCSS and SMACSS. Despite all that I can't get my CSS to work the way I can get my code to work. I search online for CSS best practices and find things like naming, formatting and a few tips and tricks. Never a deep understanding of how to create decoupled CSS. Perhaps it is just impossible. I don't feel like it should be. I feel like it should be possible to create a design language of reusable elements that can be composed.
Since all that is very abstract and it is hard to discuss without an example. Here is an example of the challenges I run into. This is based on a situation involving bootstrap, but I have simplified the styles. So please understand the styles are the way they are because that is what makes sense for the rest of the site and this example isn't about some trivial change that makes it work in this exact case.
Example:
Code for this is on jsbin.
I have a panel module with header and content. Typically the header contains an h2 and one or more button actions:
Note, the equal padding around the header and the actions float right. This design is responsive and when the panel is narrow, the actions must drop below the title. Though there is actually an issue when that happens in that there is no space between the title and button.
But really, the panel is a module that can have anything it its header. This should follow the OOCSS principle of "separation of containers and contents". So it shouldn't really matter what we put in the panel header. We want it to work well.
Now on a particular page it make sense to put a select list in the panel header. Like with Bootstrap there are many styles that pertain to forms, so we use these styles here as well. The result looks something like:
Notice that because the form-group (per Bootstrap) has a bottom margin there is now double the space at the bottom of the header (the bottom margin provides correct spacing in forms with multiple form groups). I am in agreement with our designer that the double space is wrong, it should be an equal amount of space as the top (like in the simpler example). I found a good article on ways to try to deal with this. However, the "best" option at the end (uses *:last-child) which is the one I like doesn't work here because the form is not the last element in the container because the action button must float below the select list when the window is small. Also, I feel like situations like that can always arise. Note that in this case when the window is small and the button floats below the select, the spacing is good because the margin on the form-group provides spacing between them.
Additionally, the designer says the button should be vertically aligned with the select (looks better with bootstrap because the inputs are the same height). It feels like there is no way to accomplish that which isn't very specific to the particular combination of elements here or to the particular page this appears on. That is, I can't imagine a generic best practice for making things like that line up right.
CSS for the above is too long to include in this already long question, but again check out the jsbin.
Restatement of Question:
Again, I am not looking for specific CSS that will fix this particular example. I want to know what best practices will allow me to create CSS for decoupled design elements that can be freely combined without constantly running into issues like the above.
On composability in CSS
Position, dimensions of children should be responsibility of parents
What are the best practices for creating CSS such that various design
elements are decoupled?
I have given this subject considerable thought and I was glad to have been sent a link to your article "CSS is Not Composable" by a colleague, which is how I found this question.
Because CSS intrinsically lends itself to creating selectors in a global space, separating decoupled modules into namespaces is a wise best practice.
You may optionally define base styles for a generic component class at the global level, but rely on namespace classes and/or IDs to apply positional and dimensional styles to the components based on where they are included.
Do not apply positional or dimensional styles directly to any component container. All other styles are defined by the component within its namespace.
In other words, the position and dimensions of a child component should be the responsibility of the parent container.
Correct:
/* A component namespace */
.my-component-A {
padding: 10px;
background-color: White;
}
/* A component styles its children as necessary */
.my-component-A > p {
margin: 0 0 1em 0;
}
/* Position & dimension applied by parent (Page A) within its namespace */
.my-page-A .my-component-A {
float: left;
margin: 0 10px 0 0;
}
/* Position & dimension applied by parent (Page B) within its namespace */
.my-page-B .my-component-A {
float: right;
margin: 0 0 0 10px;
}
/* Position & dimension applied by parent (Component B) within its namespace */
.my-component-B .my-component-A {
margin: 10px;
}
Incorrect:
/* Position & dimension applied by component within its own namespace */
.my-component-A {
float: left;
margin: 0 10px 0 0;
padding: 10px;
background-color: White;
}
/* Position & dimension now have to be overridden by parent */
.my-component-B .my-component-A {
float: none;
margin: 10px;
}
By using the parent component or page namespace to apply position and dimension to child components, you create a system of fully composable decoupled modules. And because a component will never change its own size or position, the developer who maintains the parent component or page has assurance that they are in control of the layout of its children.
If you are consistent and intentional, each component is capable of being placed into any other component. And because it doesn't define its own size or position, it flows into the parent container with its browser default positional and dimensional styles or with the styles provided by your global reset.
You, as the developer who maintains a page or parent component, have complete freedom to modify the layout of everything under that namespace without needing to apply overrides. And if your team is on board with this best practice, you don't need to worry that namespaced style changes made to a child component maintained by someone else will break the layout of the page or parent component you maintain.
Every component is position- and dimension-ignorant, relying entirely on its parent component or page to define its placement and size as necessary.
In your example, we can apply this principal to create a form group component that can be placed on a page and into other components at various depths while relinquishing control over layout to the page or parent component.
/* Component Base / generic reset */
.component {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* Use generic page and component class to target all child components at once */
.pagewrapper > .component {
margin: 20px;
}
/* Component: Panel */
.component.panel {
/* No positional styles defined on component container */
border: 1px solid Black;
}
.component.panel .panel-header {
/* `display: table` is a great legacy & cross-browser solution for vertical alignment */
display: table;
position: relative;
overflow: auto;
border-bottom: 1px solid Gray;
}
.component.panel .panel-header > * {
/* set all immediate children as table-cells to get vertical-alignment */
display: table-cell;
padding: 10px;
table-layout: auto;
border-collapse: collapse;
vertical-align: middle;
}
.component.panel .panel-header > .actions {
width: 1%;
}
.component.panel .panel-header h2 {
margin: 0;
font-size: 25px;
}
.component.panel .panel-content {
/* Exclude bottom padding and apply margin-bottom to immediate children instead */
padding: 10px 10px 0;
}
.component.panel .panel-content > * {
/* All immediate children of the container get a bottom margin */
margin: 0 0 10px;
}
/* Component: Form Group */
.component.form-group {
/* No positional styles defined on component container */
padding: 10px;
background-color: Beige;
}
.component.form-group label {
display: block;
}
/* Component position and dimension are namespaced to the parent */
.pagewrapper.home > .component.form-group {
/* Use child selector to limit scope of namespaced components where a component may exist multiple times as descendants of the same ancestor. */
/* You may override any other styles such as background-colors */
background-color: Lavender;
}
.component.panel .panel-header .component.form-group {
/* Positional style is always applied in the context of a parent container… */
margin: -10px;
}
.component.panel .panel-content .component.form-group {
/* …because it may need different positioning even within the same parent component. */
margin: 0 -10px;
}
.component.panel .panel-content .component.form-group:first-child {
/* Strategically use pseudo-class selectors… */
margin: -10px -10px 0;
}
.component.panel .panel-content .component.form-group + * {
/* …and sibling selectors (and other selectors as warranted). */
margin-top: 10px;
}
<main class="pagewrapper home" id="my-page-A">
<!-- Position and dimension defined by page…
`.pagewrapper > .component` -->
<section class="component panel" id="my-panel-A">
<div class="panel-header">
<h2>Title</h2>
<div class="actions">
<button>Add</button>
</div>
</div>
<div class="panel-content">
<p>Content</p>
</div>
</section>
<section class="component panel" id="my-panel-B">
<div class="panel-header">
<!-- Position and dimension defined by parent component…
`.component.panel .panel-header .component.form-group` -->
<div class="component form-group" id="my-form-group-A">
<label>A Label</label>
<select>
<option>Something</option>
</select>
</div>
<div class="actions">
<button>Add</button>
</div>
</div>
<div class="panel-content">
<p>Content</p>
<p>More content</p>
</div>
</section>
<section class="component panel" id="my-panel-C">
<div class="panel-header">
<h2>Title</h2>
<div class="actions">
<button>Add</button>
</div>
</div>
<div class="panel-content">
<p>Content</p>
<!-- Position and dimension defined by parent component…
`.component.panel .panel-content .component.form-group` -->
<div class="component form-group" id="my-form-group-B">
<label>A Label</label>
<select>
<option>Something</option>
</select>
</div>
<p>More content</p>
</div>
</section>
<!-- Position and dimension defined by namespaced page…
`.pagewrapper.home > .component.form-group` -->
<div class="component form-group" id="my-form-group-C">
<label>A Label</label>
<select>
<option>Something</option>
</select>
</div>
</main>
CSS is not meant to be separate. It is intended to have a parent to child cascading effect and can be quite powerful, reliable and resilient when applied well. OOCSS is close to what you want but not quite. With OOCSS the intention is to put common attributes in a single class that can be reused for many instances.
I think what you may want to do is look into Web Components and the use of Shadow DOM. It allows you to create your widgets so that they have their own styling separate from the main page DOM and can reduce the chance for unwanted styling even further.
EDITED: I know you said you are looking for best practices and not solutions. However, I felt I should provide some possible code samples as possible "best practice" solutions to your posted situation. For more control you you should utilize more specific css selectors as they will be given the higher importance when rendering. As a "best practice" for greatest control you should use containers with unique ID's that you can use to target sections of your html with greater specificity (ie. #mainContent, #sideBar, #myWidgetName, etc.). Then you can pair these with various CSS3 Selectors to increase the specificity and achieve greater control.
TLDR: General CSS Best Practices
Start with Base styles (OOCSS is good for this)
Add unique ID's to your important container elements
Use Container ID's, classes, CSS3 selectors, etc. to specifically
target elements inside those containers and override base styles as
needed
Also keep in mind that where you place your rules are important (top of stylesheet, bottom of stylesheet, inline, etc.)
/* ----- YOUR ORIGINAL STYLES -----*/
/* General form styles */
.form-group {/* like bootstrap, need space between form inputs */margin-bottom: 10px;}
.form-group label {display: block;}
/* Panel styles */
.panel {border: 1px solid black; background-color: white; margin: 20px;}
.panel-header {padding: 10px; border-bottom: 1px solid grey;}
.panel-header h2 {font-size: 25px; margin: 0px; display: block; float: left;}
.panel-header .form-group {float: left;}
.panel-header .actions {float: right; margin-top: 2px; /* nudge down to try and line up with title */}
.panel-content {padding: 10px;}
/* generic clear fix */
.clearfix:after {content: ""; display: table; clear: both;}
/* ----- SUGGESTED SOLUTION STYLES -----*/
.panel-header {position:relative;/* will assist with button alignment */}
.panel-header > *:nth-child(n) {
margin-bottom: 0;/* zero out the bottom margin of all direct children of ".panel-header" */
}
#media (min-width: 768px) {
.panel-header .actions { /* now that the bottom margins are set this will position the button to be aligned to the bottom of the container */
bottom: 10px;/*matches .panel-header margin*/
float: none;
position: absolute;
right: 10px;/*matches .panel-header margin*/
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="panel">
<div class="panel-header clearfix">
<h2>Title</h2>
<div class="actions">
<button>Add</button>
</div>
</div>
<div class="panel-content">
Content
</div>
</div>
<div class="panel">
<div class="panel-header clearfix">
<div class="form-group">
<label>A Label</label>
<select>
<option>Something</option>
</select>
</div>
<div class="actions">
<button>Add</button>
</div>
</div>
<div class="panel-content">
Content
</div>
</div>
</body>
</html>
I have a list of video thumbnails displayed on page. Of course they don't fit in one line, so multiple lines are used and I would like them to be spaced equally (in other case layout look broken). My current markup is
.thumbs {
width: 76%;
float: left;
margin: 0px 1em;
text-align: justify;
background-color: #DEE;
}
.thumb {
display: inline-block;
text-align: left;
}
markup is:
<div class="thumbs">
<div class="thumb">
<img src="http://placehold.it/160x120">
<div class="title">Test</div>
</div>
<div class="thumb">
<img src="http://placehold.it/160x120">
<div class="title">Test</div>
</div>
<!-- and so forth... -->
</div>
Same in JsFiddle: http://jsfiddle.net/cPm9f/
Everything is ok except the last row: I expect it to be spaced as previous rows, but space differs :( I can't use a table or just stuff a bunch of invisible stub elements because this is a foundation for responsive design so amount of columns displayed will be dependent
on width of device screen.
Any ideas how to make the last row space equally to previous ones?
UPD: There's opinion by cimmanon that what I want should be implemented differently. If so then how?
Your problem is the interpretation of text-align: justify. The last line is commonly not justified, because if the last line is rather short, the letters would need to have an absurd spacing.
Workaround:
text-align: justify;
text-align-last: justify;
But to my knowledge text-align-last is only supported by IE [EDIT: and Mozilla with -moz-text-align-last], so let us just fake another line of justifiable text for the others:
.thumbs:after { display: inline-block; width: 100%; content: ""; }
http://jsfiddle.net/TWgDh/
.thumb:last-child {
float:right;
}
? :)
http://jsfiddle.net/cPm9f/1/
As mentioned above, you can use that but just be aware that the last-child CSS pseudo-class isn't supported in any IE browsers below IE9. I don't know what you plan on supporting but it's worth knowing. The first-child pseudo-class, however, has some support in earlier versions of IE.
I have a page that basically displays all work orders for a given day. I have tried to create the HTML so that I can use page-break-after: always to create a logical print page break and continue on. However when the user prints the page, there are often overlaps, multiple work orders on the same page, etc. I simply want to enforce a hard page break that Firefox, Safari, and Chrome will listen to.
My HTML looks like this
<div class="WOPrint">
<div class="WOHeader">
<h1>Header stuff</h1>
</div>
<!-- content -->
</div>
<div class="WOPageBreak"></div>
<div class="WOPrint">
<div class="WOHeader">
<h1>Header stuff</h1>
</div>
<!-- content -->
</div>
<div class="WOPageBreak"></div>
<!-- repeat N times -->
<div class="WOPrint">
<div class="WOHeader">
<h1>Header stuff</h1>
</div>
<!-- content -->
</div>
<div class="WOPageBreak"></div>
and my CSS is basically like so:
.WOPrint
{
max-width: 100%;
padding-bottom: 3em;
}
.WOHeader
{
display: block;
page-break-inside: avoid;
}
.WOPageBreak
{
height: 1px;
width: 100%;
float: left;
page-break-after: always;
display: block;
}
EDIT
In a hackish attempt I have played around with setting the WOPrint class min-height. Changing it to 9 inches seems to give me enough margin room for printing from all Safari, Firefox, and Chrome when I have it set to a standard US paper size. This is certainly not the way I would like to fix it, but I also don't want to have to render to PDF.
.WOPrint
{
max-width: 100%;
padding-bottom: 3em;
min-heihgt: 9in
}
short answer. You can't it's not consistetly supported across all browsers. there is slightly better support for page-break-before than page-break-after though...
see page-break-before compatibility and page-break-after compatibility
you could also try embedding a Ctrl-L in the page at those points thought I'm pretty sure a lot of printer drivers are gonna ignore that.
By setting the min-height in the WOPrint CSS class I'm able to fake an approximate page break for a standard height page:
.WOPrint
{
max-width: 100%;
padding-bottom: 3em;
min-height: 9in;
}
All you need is
.WOPageBreak
{
page-break-before: always;
}
However, you'll also want to add "overflow:visible" to the body tag because without it Firefox will only print the first page.
You may also get more consistent results if you set margin:0 on the body when printing, like so:
#media print{body{margin:0}}
I understand that there are several questions here about this problem, but I have a rather unique predicament. I'm working on a template that has to include certain tags, and has to work with other elements that are added to the template after I upload the code. I wouldn't worry about this, but I am having a time trying to get the footer to display at the bottom of the page. I can't alter anything about the footer, and it displays at the bottom of the div I'm using as a wrapper. The problem is if I set the height to a fixed value, there can only be so many comments made before the comment div overlaps the footer. I've tried several different solutions including setting the container div's height to auto, overflow to auto, bottom margin to 65 (height of the footer), and setting the overflow to scroll for the Comments div (resulted in very loose comments).
Here is an example of the problem and the template as it stands.
Here is the CSS styling for the container div (div id=Main)
#Main {
margin: 0px auto auto auto;
background-color: #808080;
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: medium;
font-variant: normal;
color: #FFFFFF;
width: 900px;
position: relative;
}
Here's the CSS styling for the Comments div
#Comments {
background-color: #008080;
width: 450px;
height: auto;
top: 1750px;
left: 450px;
position: absolute;
overflow: auto;
}
And here's how the divs are stacked in the body
<div id="Main">
...
<div id="Comment_Form">
<!--[COMMENT_FORM=400,200]-->
</div>
<div id="Comments">
<!--[COMMENTS=400]-->
Comments
</div>
</div>
Since the page is going to be image heavy, I'm trying to keep the code lightweight (and probably failing at it pretty badly).
Thank you for your help and I'll post the template as of now if anyone needs it.
EDIT:
Okay, it's occurred to me that a) I need to redo the CSS and the divs that I have down, and b) I have no clue how to do it using pure CSS, or at least with out fighting it as one of you has said. What I'm trying to achieve is this:
I have no clue How to do this. and any help would be greatly appreciated (as well as any way to avoid having each and every element in its own div)
You seem to be really fighting your CSS on that page. Most of your elements are positioned absolutely within your #Main class. This will force you to specify a lot more layout than you really want to. It also means that if you have a variable quantity of comments or dynamic content, you'll find it that much harder to expand your content containers without others getting in the way.
I would strongly urge you to look at CSS frameworks or approaches that take advantage of grid layouts such as Nicole Sullivan's OOCSS framework.
You'll find that the structure (which has plenty of good, workable examples) is easy to follow and lends itself much more readily to the sorts of layouts that you're trying to achieve.
I hope this is helpful.
Here is a very basic layout that you can use.
In your CSS:
#header, #content, #comments{
margin: 0 auto;
width: 960px;
overflow: hidden;
}
#author-comments{
width: 100%;
}
#comment-box{
float: left;
width: 50%;
}
#comment-list{
float: right;
width: 50%;
}
In your markup:
<div id="header">
Header
</div>
<div id="content">
Contents
<div>
<div id="comments">
<div id="author-comments">
Author comments
</div>
<div id="comment-box">
Comment box
</div>
<div id="comment-list">
Comment list
</div>
</div>
It's really important that you use markup that makes sense without the styles. Don't see divs as plain boxes but as actual content containers that give structure to your document.
On a side note, you mentioned that you were concerned about the ammount of divs to keep your file light, compensating for the amount of images you're using. Don't worry about this. Text documents (such as HTML) are nothing compared to images in terms of file size. However, his doesn't mean you should throw markup as if it was free ;)
One last thing. I noticed that you are using <img> elements to render your decoration images. Try using CSS to set them as background images in the corresponding <div>s. This not only will help you to make cleaner and easier to implement structures, but also will draw a line between the images that represent content and those that represent decoration.
I'll write without any testing how I would code the layout on your image:
HTML:
<div id="header" class="centered"></div>
<div id="content" class="centered">
<div id="navigation"></div>
<div id="content"></div>
</div>
<div id="comments" class="centered">
<div id="author-comments" class="centered"></div>
<div class="centered">
<div id="comment-field"></div>
<div id="user-comments"></div>
</div>
</div>
CSS:
* { margin:0px; padding:0px }
html { height:100% }
body { height:100% }
.centered { position:relative; margin:0 auto; width:960px }
#header { height:100px; background:#333 }
#content { overflow:hidden }
#author-comment { overflow:hidden; margin:30px auto }
#comment-field { position:relative; float:left; width:480px; overflow:hidden }
#user-comments { position:relative; float:left; width:480px; overflow:hidden }
Sorry, got no time to test now, but on first view, I don't see any problems with this code - write comments, if something doesn't work