Forbid flexbox items to flex w/o use of * selector - html

I work with BEM and use a flexbox container purely for alignment and responsive design purposes. The problem is that sometimes it also wants to scale its daughter elements, which I don't want. Like this:
.card {
width: 120px;
background: gray;
}
.container {
display: flex;
align-items: center;
}
.flex-item1 {
width: 50px;
background: blue;
}
.flex-item2 {
overflow-wrap: normal;
background: green;
}
.ruller {
width: 50px;
background: gray;
}
<div class='card'>
<div class='container'>
<div class='flex-item1'>
I'm picture 50px wide
</div>
<div class='flex-item2'>
I'm long text
</div>
</div>
</div>
<div class='ruller'>
My width is 50px
</div>
Here is the blue element is getting scaled and its rule width is ignored.
One direct solution for this is to just explicitly forbid flexing for every element.
.flex-item1 {
width: 50px;
background: blue;
flex: none; /* the fix */
}
But container is a general class, I'm using it in tens of different situations, I don't want to add more CSS code to all possible classes of its daughter elements, nor do I want to add another class like container-item to all those elements in HTML.
Another direct solution for this would be
.container * { /* the fix */
flex: none;
}
But this goes against general BEM guidelines on using selectors. I would like to avoid using * selector here.
Is there a way third way to do it? I.e. a way that doesn't add any CSS rules to styles of daughter elements and which does not use * selector.
What makes me ask such a question is the existence of rules like align-items, which are placed to the parent element (i.e. flexbox itself) by the acting on daughter elements (i.e. flex-box items). I imagine my solution would be is something like this:
.container {
display: flex;
align-items: center;
flex-items: none; /* a pseudo rule, which doesn't exist and need to be replaced by other rules to work */
}

If you insist on following BEM without exception, then you should have the rules you need within classes you've defined for your elements. That would be the BEM way. You may not like having that code in 20-30 different places as you say, but that is the tradeoff of BEM.
Personally I combine BEM with utility classes when it makes sense, I don't believe that following BEM blindly to the letter produces cleanest and easiest to maintain codebases.
On the other hand rise in popularity of Tailwind goes to say that BEM and similar methodologies don't work for all.
All this being said, I would suggest sprinkling some utility classes on your BEM project and enjoying best of both worlds.

Related

Is there a way to add margin or padding to list style images?

I am trying to create a webpage.In the footer of the page I have a lists.My code displays the first image whereas it should look like the second image.
What I have coded
What it Should look like
For the code You can see it from github repository :
"https://github.com/nganbarova/Huddle.git"
I'd recommend you use different classes for each LI item and then make use of the ::before pseudoelement. You can then style and move that wherever you need to.
li {
position: relative;
}
li.myClass::before {
content: url('image.png');
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 20px;
}
For an accurate answer, I need to see your code first, but there are some general recommendations for you. if you are using font-awesome you can simply add this to your stylesheet file:
li i { margin-right:5px; } or li fa { margin-right:5px; }
If you are using an image as an icon use this one:
li img { margin-right:5px }
You can change the property value of the margin to any value that works fine for you.
You haven't shown your code, so I'll give you generic and easy to understand methods for indenting. But it would be much more efficient if you pasted your code here.
1 Method using flex:
For the parent container (within which there are points) you specify the exact height and flex rules. These items will be distributed evenly across the container:
parent_selector {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 500px;
}
2 Method using grid:
Grid has a grid-gap rule that sets the spacing without affecting the first element:
parent_selector {
grid-gap: 10px;
}
3 Method using margin and pseudo-class :not and :first-of-type:
Using the :not and :first-of-type pseudo-classes together will allow you to indent every inner element except the first element.
parent_selector p:not(:first-of-type) {
margin-top: 10px;
}
All of these methods are easy to use, but it would be better if you showed your code. If you have any questions, write here in the comments.

Get attribute value in LESS?

In css we have something similair for :pseudo elements. According to this, it will come in the future. At the moment its not supported by any major browser http://caniuse.com/#feat=css3-attr
.test {
display: inline-block;
background-color: gray;
color: attr(data-color); /* Doens't work in css */
width: attr(data-width px);
}
.test:after {
content: attr(data-name);
}
<div class='test' data-name=" - CONTENT" data-color="#f00" data-width="200">test</div>
But what i want is, lets say ive the following div
<div data-color="#f00">...</div>
In LESS i want to be able to pick that color through the data attribute.
.example-class {
color: attr(data-color); /* Something like this */
}
Is this, or something similar, possible using LESS?
Considering that LESS compiles to CSS anyway, and therefore never knows about the HTML, that doesn't seem possible. That is the entire reason why the attr() function is in CSS, not LESS.

CSS - efficiently using classes

I have written a class for a textfield with a certain style. The field appears at 2 very different place within the website, with different parent elements. The second need another margin-top. What is an efficient way to change the original margin-top, since I cannot use pseudo-classes?
js fiddle
HTML
<div class="some_parent">
<div class="my_styled_field"></div>
</div>
.....
<div class="some_other_parent">
<div class="my_styled_field"></div>
</div>
CSS
.my_styled_field{
margin-top: 2rem;
}
.some_other_parent .my_styled_field{
margin-top:3em; //what ever you want
}
this is the way to apply some other styles to the same class, having different parents .
Pretty sure the most efficient way - most of the time - as in best performance, would be to add another class to your second styled_field.
If you add another class to your second styled_field, you would need only 1 reflow to reach it:
.newclass{margin-top:5px;}
Whereas using the descendant selector which others are selecting is surely worse performance, this means the browsers has to check a lot of elements recursively:
.parent .styled_field
If you don't want to add a class for some reason, better performance than the descendant selector would be the child selector:
.parent > .styled_field
When thinking about css performance, remember that even though we read left-to-right, browsers read right-to-left.
Where we would check all .container elements for an image-tag, browsers find all image-tags - then checks if they are in a .container
Using CSS class hierarchy:
.some_other_parent .my_styled_field {
margin-top: 2em;
}
Youc can do this:
FIDDLE EXAMPLE
.some_parent .my_styled_field{
width: 3rem;
height: 3rem;
margin-top: 2rem;
background-color: red;
}
.some_other_parent .my_styled_field{
width: 4rem;
height: 4rem;
margin-top: 4rem;
background-color: green;
}
This way, you aply style to .my_styled_field depending on his parent element.

Is there a css pseudo selector for overflow?

I'm trying to alter the style of something based on wether or not its parent div is being overflown.
.pDiv { display: block; width: 300px; height: 100px; border: 1px solid rgb(0,0,0); }
.cDiv { display: block; padding 4px; border-bottom: 1px solid rgb(0,0,0);
.pDiv:overflow .cDiv { border-bottom: none; }
<div class="pDiv"><div class="cDiv">child 1</div><div class="cDiv">child 2</div><div class="cDiv">child 3</div><div class="cDiv">child 4</div><div class="cDiv">child 5</div></div>
is it possible to do something like this? I would use the last-child pseudo-selector, but the number of children can vary, so I want it to remove the border-bottom of the last-child ONLY IF the parent div is being overflown. I want a pure CSS solution too please, no JS!
CSS cannot select based on used or computed styles of any kind, so you're out of luck.
It seems a handy solution for this is being cooked up: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries
According to css-tricks, the feature "#container brings us the ability to style elements based on the size of their parent container."
You should already be able to use it, but beware that not every browser supports this yet.
This way, you might (read the note) be able to get out with something like:
.parent-div {
max-height: 10rem;
overflow-y: auto;
container: size;
}
#container (min-height: 10rem) {
.parent-div:last-child {
border-bottom: none;
}
}
The main idea here being that if the element reached it's maximum height, then it's all but always overflowing — so we just apply the style so long as it's at it's maximum height.
Unfortunately, my own browser does not support this yet, so I can't guarantee you it would work the exact way as it is written above. But if you refer to the 2 pieces of documentation I provided, you should be able to come out on top 🤓
Note:
The css-tricks page also mentions that "Currently, you cannot use height-based container queries, using only the block axis". I'm hoping this simply means using the full size axis is necessary in this case, but I'm not able to test this.
If someone could verify whether this solution works and then leave a comment here, that would be very much appreciated. I'd edit this answer and credit the person.

Change specificity by child

I'd like to integrate a theme tag to my elements so they appear in diffrent colours. But since the css selectors have the same css specificity the latest overrides the earlier defined rule.
this is an example that shows my problem:
<div class="red">
<div class="box">This should be red</div>
<div class="yellow">
...
<div class="box">This should be yellow (nested in x levels under the div.yellow)</div>
...
</div>
and here my css
.box { width: 100px; height: 100px; }
.yellow { background-color: yellow; }
.red { background-color: red; }
the box should be listed somewhere, but as soon as it is a sub child of another color definition it should been overwritten.
thanks for any help!
You shouldn't really be doing things this way -- if your theme changes, then suddenly things with class yellow may actually be blue, for example. I would suggest finding a common way of naming things (even if it's just colour1, colour2, colour-highlight...) and then specifying those styles. You can then look into the way your pages are designed and make the rules more specific as necessary (either by using !important or by making the rule more specific, e.g. .colour1 becoming .box .colour1 or div.colour1).
Try:
.box { background-color: inherit; }
See:
http://jsbin.com/imube/edit
I don’t quite see the problem. Here’s what I get with that code:
alt text http://www.pauldwaite.co.uk/images/so/1905834.png
You probably need to use CSS's !important keyword eg:
.yellow { background-color: yellow !important;}