Is there a way to put relationships/contraints into CSS? [closed] - css

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In every design tool or art principle I've heard of, relationships are a central theme. By relationships I mean the thing you can do in Adobe Illustrator to specify that the height of one shape is equal to half the height of another. You cannot express this information in CSS. CSS hard-codes all values. Using a language like LESS that allows variables and arithmetic you can get closer to relationships but it's still a CSS variant.
This inability in my mind is the biggest problem with CSS. CSS is supposed to be a language that describes the visual component of a Web page but it ignores relationships and contraints, ideas that are at the core of art.
How possible is it to imagine a new Web design language that can express relationships and contraints that can be implemented in JavaScript using the current CSS properties?

Are you looking for something like CSS Scripting Layout Specification or Constraint Cascading Style Sheets for the Web? Both are still in the research/prototype stage though.
The CSS Scripting Layout Specification has been implemented as a Google Chrome plugin, it seems.

If you set the size attributes using a percentage, and place the element as a child of the one you're sizing, you will be able to size an element relatively to another. Then, use positioning to move the child outside the parent physically.

There was also a JavaScript Style Sheets spec from Netscape back in 1996, http://en.wikipedia.org/wiki/JavaScript_Style_Sheets.
The CSS Scripting Layout Specification is not a Chrome plugin. What is provided is a proof of concept. Many people are not convinced that JavaScript can perform well enough for CSS layout due to Microsoft's CSS Expressions implementation that had severe performance issues.
It is limited to layout as this seems to be the biggest complaint with CSS. It's aim is to give power users the ability to do nearly anything they want, but at the same time make it such that layouts can be encapsulated, referenced, and reused by novice users.

Directly, this isn't something you can do in pure CSS without causing more trouble than helping due to varying amounts of support from different browsers.
Indirectly,frameworks like Less or by running your CSS through a server-side script before sending it to the client are your best bet but, like you said, not ideal.
In Javascript, using jQuery to set one element's height property based on another's outerHeight is probably the start of a decent solution, but I can't find any code examples people have written to solve your specific problem. I'd imagine it might be something like this, though:
var totalHeight = 1000;
$("#div2").height(totalHeight - $("#div1").outerHeight());
That would set the height of one based on the height + border + padding of the other. In order to be more robust, there's more that needs to go into it than that, but it's the beginning of a solution.

You may want to take a look at Clever CSS, a pythonic approach to writing CSS. It includes variables, arithmetic, you can even do operations on colors.
I'm also looking after one such approach to writing styles, something that is a higher level over CSS. But one of the big problems, I believe, will be the fact that CSS style sheets are often written by designers and not programmers, using design tools that probably allow them to work at a higher level and generate the CSS afterwards. What for us programmers could be a good flexible approach may not work because it is too geekish for designers.

Use of percentages to determine the height is to express a relationship with a hard-coded value.
"if you set the size attributes using a percentage, and place the element as a child of the one you're sizing, you will be able to size an element relatively to another" BUT ONLY IF parent elements heights are expressed explicitly (and this apply iterating until the html element).
In CSS Level 2 "The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), the value is interpreted like 'auto'".
But from Revision 1 "percentage heights on absolutely-positioned elements are no longer treated as 'auto' when the containing block's height is not explicitly specified."
With absolute positioning this solution breaks because "For absolutely positioned elements whose containing block is based on a block-level element, the percentage is calculated with respect to the height of the padding box of that element. This is a change from CSS1, where the percentage was always calculated with respect to the content box of the parent element."
In the following code the inner wrapper divs heights will collaps using absolute positioning, losing the ability to use them to place margins.
<body>
<style type="text/css">
html, body {
height: 100%;
}
div#wrapper {
height: 100%;
}
div#content-wrap {
height: auto;
}
div#wrapper-upper-half {
height: 50%;
background-color:aqua;
}
div#wrapper-lower-half {
height: 50%;
background-color:fuchsia;
}
</style>
<div id="wrapper">
<div id="wrapper-upper-half">
</div>
<div id="content">
</div>
<div id="wrapper-lower-half">
</div>
</div>
</body>

Related

When using BEM, is it illogical to have a block nested inside its element?

Let's say I want to have a title block, and for styling considerations I need to nest it inside a div with some special CSS styling (e.g. I want specific border and spacing styling). Let's call this one box. The box just serves the style the title inside it.
The fact I need to have box at all just has to do with the limitations of CSS, so it doesn't make sense for the box to be considered a block in BEM terminology. It doesn't even make sense as a DOM element. But title is located inside box.
It makes sense to me to give box the class title__box because it doesn't make sense without title. However, all examples of BEM seem to assume the element is always a DOM child of the block it's in.
To answer your question plainly without investigating further into this, no.
You would have to have something like the following
<div class="decorator">
<h1 class="title">blah blah</h1>
</div>
or
<div class="title">
<h1 class="title__heading">blah blah</h1>
</div>
When using BEM you have to think in terms of "blocks", "elements" and their reusability. In particular, consider this from a developer perspective: you don't want to end up in a particular scenario where the developer will build the title in question and forget an element or an attribute and get mad trying to figure out why it doesn't work. This gives you consistency and replicability of your markup.
I have no specific insight on why you need the <div> and what are the CSS limitations that you're talking about, but I will take your word for it.
So I'm going to ask: have you thought of cleaning up the markup using pseudo selectors, or using the heading as the aforementioned container and using inline anonymous elements (i.e. <span>s)?
I hope this helps solving your problems.

css positioning far right - with minimum width

I am a mostly skilled server-end developer, and am creating an ambitious website project - all by myself. I know c#, MVC, T-SQL, LINQ, and ASP.NET pretty well. Obviously, since I'm working by myself, I have knowledge in design too. I'm obviously good with html (who isn't?). And I absolutely love jQuery! The thing is, I'm decent in my understanding of css, but css is my least knowledgeable trait. I understand programming, I also am good in design, not just because I have a decent level of knowledge in css (and jQuery) - but also because I just know what looks good (I can draw and paint on real paper too).
The thing is, I know I can probably do this with jQuery code, but I was wondering if this could also be done with css alone. On my main design (Views/Shared/_Layout.cshtml) - I made the body to have a "min-width: (my value);" attribute, which, obviously isn't supported with older browsers, so I also included a transparent image of a default width of 1px that I set to stretch to my desired width also - it works in controlling the width of the page (to the minimum I desired). But - I have a site header div which resides at the top of the page. I have a part of that header div with elements positioned on the far right - which is nice when the browser is on a device that is large enough and the browser is in decent size, but once the browser is set to a size less than my desired minimum width, then the scroll bar shows up, and I can move it around as expected. But, the elements in that header div do not stay to the far right in conjunction with my minimum width - but stay on the right of the current window size instead. I have the main div holding the elements itself set to be in fixed position, I tried making those elements relative with no success. I tried a few ideas, the problem still persists.
So, as I said, I am well aware of concepts using jQuery that can do what I have previously described I desire in these regards, but, as I also said, I know a decent amount of css, but am the least close to an "expert" in css than anything else I know. I just have a strong suspicion what I desire here can be done with css and css alone (also, it would be nice to have it compatible with most browsers, or at the least most browsers made after the year 2008).
Can someone please give me some good information in these regards?
I just remembered asking this question.
I actually found a way to go about doing what I wrote I desired here through some experimentation that eventually got me to where I needed to be. What I did was instead of using relative positioning - which I thought was the proper way of doing this, I used absolute positioning inside the absolute positioned top header div. I didn't think this would be the solution at the time of asking the question, I assumed setting something as absolute positon - even inside something that is already absolute positioned - would put it in a new context of absolute positioning like any absolute positioned element inside the body tag. What I discovered was if I put an absolute positioned element inside another absolute positioned element - the context of the absolute positioning was based on the original absolute positioned element - so top (or left for that matter) 0px wasn't 0px from the context of the body (the very top of the page) - but - 0px from the element that the element is inside of. I think that's a pretty explanation of it, so I'll end explaining it here.
I'm sure there's plenty of people that know css much more than I do, and think this issue I had here is so basic, but, I did ask the question, and I might as well answer it based upon the solution I used. I could've posted an example on jsfiddle like asked for in a comment, but I thought my explanation was good enough, and since no one offered an answer based on my question alone, I decided to try to address the issue with experimentation, which I had success with.

Building a grid framework with inline-block's

I'm about to update http://getcrow.eu and have one "issue" to solve that would make the framework everything I always wanted it to be.
Important to know:
Crow does not use tables, absolute positioning, floats or clearfix'es and it should stay that way.
We know that putting inline-blocks next to each other like so:
<div class="parent">
<div>Block 1</div>
<div>Block 2</div>
<div>Block 3</div>
</div>
with CSS:
.parent {
> div {
display: inline-block;
}
}
Creates white-spaces between the blocks. We also know there's a handful of solutions to prevent the white-spaces from creating space, which is highly required if creating a grid framework with this method.
Beneath I list the methods that I'm aware of and why I don't want to/can't use them:
(SKIP IF YOU WANT TO GET TO THE QUESTION)
Comments in the HTML inbetween children div's.
No-go because: it creates ugly HTML that the developer, using crow, must be aware of and work with.
Breaking lines at the end of children tags/ not using closing tags.
No-go because: same as above
Using minus (-) margins on .parent-wrapper.
No-go because: specified margins depends on document font size which mean the grid could break in responsive markup where html { font-size:{X}px; } changes.
Setting 0px font-size to .parent and "reset" the font size on children (this is the method I'm currently using).
No-go because: I don't want the developer using crow to force-set the children. I just want the inheritance to be natural without a grid that's setting the font size downwards for me.
Using Javascript to remove all white-spaces from .crow elements.
No-go because: I want the framework to be pure CSS and no js. This could also "flick" the DOM after pageload if user has bad connection.
Loading a font with font-family on .parent that has no white spaces.
No-go because: loading in an extra font just to get the grid framework is just wrong. Especially as you have to download extra files (font-files) and declare fallbacks for all browsers.
Using letter-spacing -{X}px on .parent.
No-go because: same as .3 (see above)
Using flex box.
No-go because: the framework focuses on vertical centering (if desired) and flex box lives it own life when it comes to that. I'm also making sure the grid is supporting IE8 which it does today.
So basically I'm searching for a - unknown/not yet discovered/way that I'm not aware of - for removing white spaces in between inline-blocks. I want it to be pure CSS. If you have a method that you know of/think would work - I can try it on different browsers.
Resolving this would surely make Crow the best grid framework. I'm already using it for various websites and I can tell that the possibilites are many when given the ability to easily position elements center vertically.
Sidenote:
Marking up the DOM like so: <div class="parent"><div>Block 1</div><div>Block 2</div></div> does the job just like I want it to. But that would require the developer using Crow to mark it up that way. And I don't want to rely on a framework creating that HTML.
InuitCSS (my choice of framework lately) uses a similar system. As wonderful as the use of display: inline-block; is in a grid system, it does appear that the whitespace issue, is an inherent one; with little chance of resolution beyond the current workarounds.
I agree that the use of comments or closing tags does introduce some issues with CMS entries, and a certain amount of mental overhead for the developers involved; but not an unmanageable amount.
If you want to have a look at Inuit's grids I would recommend it's GitHub found here:
https://github.com/inuitcss
I would also advise reading this issue, in-which Inuit's creator; Harry Roberts, weighs in on the various solutions this problem. Whilst it may not tell you anything you don't already know, it is an interesting (if outdated) discussion on the matter.
https://github.com/csswizardry/inuit.css/issues/170
I know that the above may not solve your issue, or even shed any light on the matter, but I hope it can be of use.
Using a float is your best option.
.parent div {
float: left;
}
Following your comments below you could use a negative margin.
.parent div {
margin-left: -4px;
}
But this may change browser to browser.

Moving divs between parent divs based on screen size display:none a bad idea?

I have a bunch of divs in a webpage that need to be moved to completely different parent divs based on screen size.
At the moment I am repeating the divs and setting the display property to either none or block etc based on screen size.
First question is is there a better way to do this using html or css only?
Secondly does the display:none allow use of duplicate div id's or is that just plain bad coding?
thanks
You can use Flexbox's flex-flow to move elements and content around with HTML. I'm not sure about browser support though. A JavaScript solution would be better in this case.
As for your second question, duplicate IDs isn't a CSS problem, it's an HTML problem. It's not allowed whether you use CSS or not. So no, don't do it.

CSS layout for vertical stacked divs to use 100% of available height

I have a layout in which two divs appear stacked vertically inside a parent div which will be a specific height (due to containing a left hand menu). I wish the two divs to take up all the available vertical space. However, they must resize depending on their content. The easiest way to explain is with a diagram:
Reading the diagrams from top to bottom, this is the scenario:
both divs take up 50% of available height as this is sufficient to contain their content (this is the default).
there is a lot of content in top div and less content in bottom div. Top div expands to fit content and squashes bottom div.
reverse situation of (2).
both divs must expand to fit their content. Containing div must expand to accomadate.
I think I could figure out how to do this with a table, see the example here which is almost correct (in chrome anyway) except the outer div doesn't expand properly.
Is there a better CSS solution to this without using a table?
I cannot use JavaScript and solution must work in all browsers... including IE6 :(
.
This can be done using CSS, with a feature called the flexible box model. It's an extension to the box model that's been in use in CSS since the begining, and allows you to do stuff like vertical stacking, etc, which wasn't possible before.
You would start off with display: flexbox;, and then use other related styles to define the characteristics of the layout you want. It is very powerful. You can read the full W3C spec for it here: http://www.w3.org/TR/css3-flexbox/
Now the bad news: It's a very recent addition to CSS. It actually has reasonably good browser support (albeit with vendor prefixes), but the problem you'll always hit is that it isn't supported in IE, not even IE9 (though it is planned for IE10)
Other browsers require vendor prefixes, so even for supported browsers you'll need to write your styles in four or five versions.
In addition - and this is the real killer - there isn't a good fall-back solution for browsers that don't support it. If you design your page using flexbox layouts, and load it into a browser that doesn't support them, it will be a disaster.
For this reason, it is hasn't really seen much use in the real world yet. It's time will come, but as long as IE9 and earlier are in use, it won't become mainstream.
You can see a full browser compatibility chart for the feature here: http://caniuse.com/#search=Flexible%20Box%20Layout%20Module
In the meanwhile, you're going to have to use a Javascript solution.
My recommendation is the JQuery Masonry plugin. I think this will be your best solution for now.
You could fake it using a 100% height wrapping div and a white border like so:
http://jsfiddle.net/cBV88/2/
You can also remove the fixed height and it will still work.
SuperStretch might get you part of the way there.

Resources