Changing CSS Property From an Array using JS - css

I am currently building a todo app, and from react, I am using CSS to custom my todo items' margin!
The problem is, I only needed the first element to have a margin-top of 110px. Here's what it'll look like when I apply it to every item - link
It's that the todolist items are too separated!
But if I removed the margin of 110px, the item is behind the textbox!
link
Is there a way to change the property of first item? I can delete the margin-top: 110px from the css file, and change the 1st item using JS. My planned function -
function addTodo() {
setList([...list, value]);
const firstItem = list.findIndex(0);
}
Thanks!

:first-of-type selector in CSS allows you to target the first occurence of an element within its container. Also, another option might be to select first child of the element, you can use :first-child pseudo-class.

There are several possibilities to solve this problem. I think the simplest one is to just build a container that contains all list items, and set it's padding-top or margin-top to 110px. The result could look like this:
.frame {
margin-left: auto;
margin-right: auto;
padding: 10px;
width: 200px;
border: 1px solid #000;
text-align: center;
}
.control-button {
position: absolute;
}
/* this is the container that holds all your items */
.items-container {
margin-top: 40px; /* in your case, it should be 110px */
}
.item {
margin-top: 10px;
border: 1px solid #000;
}
<html>
<body>
<div class="frame">
<div class="control-button">
<u>add item</u>
</div>
<!-- this is the important part, the container with the items -->
<div class="items-container">
<div class="item">
This is an item.
</div>
<div class="item">
This is another item.
</div>
</div>
</div>
</body>
</html>
I think this solution is the most simple and flexible one. You can easily add left, right or bottom margins too and you don't have to worry about which items it affects.

The simplest solution you can go with is using the :nth-child(n) pseudo class in CSS or :first-of-type.
Try this code:
.item:nth-child(1) {
margin-top: 110px;
}

Related

Style a class only inside a table

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; }

CSS: nth-of-type(2) is not being applied to class

Example page
The bottom right div containing "Student Visas" I thought would be affected by CSS:
.front-page-widget-portrait2:nth-of-type(2) .second-half {
height: 240px;
color: #FFF;
padding: 40.28436018% 40px 0 40px;
position: relative;
}
.front-page-widget-portrait2:nth-of-type(2) .second-half img {
position: absolute;
bottom: 0;
width: 49px;
margin: 0 auto;
display: inline-block;
}
It is contained in the 2nd div of class front-page-widget-portrait2, but .front-page-widget-portrait2:nth-of-type(2) is not being applied.
Can you see why not? Help appreciated.
Your markup is something like this
<div></div> <!-- Some more div elements around on the same level -->
<div class="front-page-widget-portrait2"></div>
<div class="front-page-widget-portrait2"></div>
<div></div> <!-- Some more div elements around on the same level -->
Instead of this, try wrapping your front-page-widget-portrait2 inside another div like
<div></div> <!-- Some more div elements around on the same level -->
<div class="front-page-widgets">
<div class="front-page-widget-portrait2"></div>
<div class="front-page-widget-portrait2"></div>
</div>
<div></div> <!-- Some more div elements around on the same level -->
Now, you can use a selector like
.front-page-widgets > div:nth-of-type(2) .second-half {
/* Styles goes here */
}
Let me break down the selector to explain to you how it works. We first select the wrapper element that is front-page-widgets (we just created a new one). Moving further, we use > which selects immediate children to wrapper element i.e div with a class of front-page-widget-portrait2. But as I already mentioned that nth- won't respect classes, so using it in the selector makes no sense. Lastly I use .second-half which selects the second block in your second widget.

Can I principally style the parent element based on child element using CSS3?

An Example: Only DIVs, that containing a LABEL should get the style text-align: right
Following try did not work:
div label:only-child {
text-align: right;
}
Not the label but the div should get this style.
you can use this way
div class="test" style="text-align:left"
div class="test" style="text-align:right"
The solution is to set the width of the label and display property to block. Here's the code
div{
width: 500px;
padding: 20px;
background: #fff;
border: 1px solid #ddd;
}
div>label:only-child{
text-align: right;
width: 100%;
display: block;
}
<div>
<label>adfasdf</label>
</div>
this cannot be done with CSS .
CSS = Cascading Style Sheets so by definition you can select elements from top to bottom of the HTML structure, not the other way around.
so you can't select a parent depending on it's children
you can do this with JQ , there are a number of ways to do it but this would be one of them :
$( "div:has(label)" ).css({ "text-align":"right" });
.div {
height:50px;
border:2px solid red;
margin:2px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="div">
<label>Has Label</label>
</div>
<div class="div">
<p>
i am NOT a label
</p>
</div>
<div class="div">
<label>Has Label</label>
</div>
You can't style parent element based on child element using CSS.
Since, it seems that you are trying to align the label element to right, you can do that using float as shown below:
div label:only-child {
float: right; /* instead of text-align: right */
}
Updated (parent has flexbox layout):
div label:only-child {
flex: auto;
text-align: right;
}
You cant't do this in CSS only. Well, of course you can add class to div but there is no parent selector.
But there will be in the future (selectors lvl4 - see last row of selectors overview): https://www.w3.org/TR/selectors4/

setting padding depending on number of child elements

I have a DIV element which may contain 1 or 2 Child DIVs
Is there a way to say of there is 1 Child element then the padding should be 15px otherwise 5px
It may like
<div class="container">
<div><strike>7.00</strike></div>
<div>5.00</div>
</div>
or
<div class="container">
<div>7.00</div>
</div>
You can do a trick using margin in the children to get the same effect:
.container div:only-child {
margin: 15px;
}
div {
border: solid 1px red;
}
div div {
margin: 0 5px;
border-color: green;
background: #ccc;
}
div div:first-child {
margin-top: 5px
}
div div:last-child {
margin-bottom: 5px
}
<div class="container">
<div><del>7.00</del></div>
<div>5.00</div>
</div>
<div class="container">
<div>7.00</div>
</div>
PS Use del tag instead strike that is deprecated
No, there is not.
CSS does have some complex quantity queries but these will only style the children based on their number.
It is not (currently) possible to style the parent based on the number of children as there is no Parent Selector
Based on how old this original thread is I'm not providing exact solutions, however, CSS Tricks put a great article together covering Logical CSS styling. You can find the article here.

How to space the children of a div with css?

I want a gap of say 30px; between all children of my div. E.g if I have:
<div id="parent">
<img ... />
<p>...</p>
<div>.......</div>
</div>
I want all of them to have a space of 30px; between them. How can I do this with CSS?
For an unknown amount of children you could use.
#parent > * {
margin: 30px 0;
}
This will add a top and bottom margin of 30px to all direct children of #parent.
But img is not displaying as block default, so you may use:
#parent > * {
display: block;
margin: 30px 0;
}
Vertical margins of block elements will be collapsed. But you will have margins at top and bottom of your parent div. To avoid that use the following code:
#parent > * {
display: block;
margin-top: 30px;
}
#parent > *:first-child {
margin-top: 0px;
}
This will only add top margin and removes that top margin for the first element.
The following css will work well
div > *:not(:last-child) {
display: block;
margin-bottom: 30px;
}
> selects all elements that are direct children of the div (so you don't get weird inner spacing issues), and adds a bottom margin to all that aren't the last child, using :not(:last-child) (so you don't get a trailing space).
display: block makes sure all elements are displayed as blocks (occupying their own lines), which imgs aren't by default.
You can easily do that with:
#parent > * + * {
margin-top: 30px;
}
This will be applied to all direct children except the first one, so you can think of it as a gap between elements.
Probably the easiest way is this:
#parent * {
margin-bottom: 30px;
}
or
#parent * {
margin: 15px 0;
}
Keep in mind, though, that this will get everything in #parent, including things inside the p and div tags. If you want just the direct children, you can use #parent > * (this is call the direct descendent selector) instead.
Keep in mind, <img> is an inline element by default, so you might need to do:
#parent img {
display: block;
}
for it to use the margins.
Use CSS gap property.
.parent_class_name{
gap: 30px;
}
The above CSS code will apply a gap/separation of 30px between children of the parent_class_name class.
Example: This code will apply 1rem gap between element (rows and columns).
<div class="gap_container">
<div>a</div>
<div>b</div>
<div>c</div>
</div>
.gap_container{
display: flex;
flex-direction: column;
gap: 1rem;
}
The gap property defines the size of the gap between the rows and columns. It is a shorthand for the following properties:
row-gap
column-gap
Apply row and column values separately.
gap: row-value column-value;
Learn more: w3school
Create a CSS class for them with code:
.BottomMargin
{
margin-bottom:30px;
}
And assign this class to parent's children using jQuery or manually like this:
<div id="parent">
<img class="BottomMargin" ... />
<p class="BottomMargin">...</p>
<div>.......</div>
</div>
the last one may not have one and this is also doable using jQuery.
You can try it by CSS standarts:
div > *{
margin-top:30px;
}
More info could be found here: http://www.w3.org/TR/CSS2/selector.html#child-selectors
Just put a top and bottom margin of 30px on your p element:
p { margin: 30px 0 30px 0; }
Note: the above will add this margin to all your p elements. To restrict to just this one, either add an inline style attribute:
<p style="margin: 30px 0 30px 0;">...</p>
or better use a class:
<p class="mypara">...</p>
and in css:
p.para { margin: 30px 0 30px 0; }
Btw, the notation here for margin is:
margin: top right bottom left;
Or you can individually specify top and bottom margins:
margin-top: 30px;
margin-bottom: 30px;
So you could have a class like this:
.bord { margin-bottom: 30px; }
and add this class to every element you want to have a margin-bottom of 30px:
<div class="bord">....</div>
Surest way is to add a class to all of the internal elements with the exception of the last one.
<style>
.margin30 {
margin-bottom: 30px;
}
<div id="parent">
<img class="margin30" ... />
<p class="margin30">...</p>
<div>.......</div>
</div>
This way, additional elements can just be tagged with the class. Remember that you can multiclass style elements by separating them within the class value in the tag with spaces, like so:
<img class="margin30 bigimage" ... />
Finally, you can attach the classes dynamically with Javascript (code off the top of my head, not tested, no sanity checks or error handling, ymmv etc.):
function addSpace(elementId) {
children = document.getElementById(elementId).childNodes;
for (i=0;i<(children.length - 1);i++)
children[i].className = "margin30 " + children[i].className;
}

Resources