Style same class in another element with + selector differently - html

There's a website that has code like I've put on the following jsfiddle:
https://jsfiddle.net/roa8k7js/
The site has very complex css styling, over 10,000 lines. In switching this site over to WordPress, the styling was all maintained and everything was put into a theme.
As such, every <section> is now inside a wrapper. Because of this, the styling does not function correctly.
The <section> padding is determined by a number of rules, including at least one major rule that uses the + selector.
The rule looks like this:
#layout1 .option-b:not(.custom-bg-image) + .option-b:not(.custom-bg-img)
{
padding-top: 0;
}
Since the wrapper was added, the + selector won't correctly identify the pattern:
<div class="wrapper1">
<section class="option-b">This is some text</section>
</div>
<div class="wrapper1">
<section class="option-b">This is some more text - there shouldn't be any padding on top of this one</section>
</div>
section {
border: 1px solid black;
}
#layout1 .container1>section {
padding-top: 2em;
padding-bottom: 2em;
}
#layout1 .option-b:not(.custom-bg-image)+.option-b:not(.custom-bg-img) {
padding-top: 0;
}
#layout1 .container1>.wrapper1>section {
padding-top: 2em;
padding-bottom: 2em;
}
<div id="layout1">
<div class="container1">
<section class="option-b">This is some text</section>
<section class="option-b">This is some more text - notice how there isn't a padding top on this one</section>
</div>
</div>
<div id="layout1">
<div class="container1">
<div class="wrapper1">
<section class="option-b">This is some text</section>
</div>
<div class="wrapper1">
<section class="option-b">This is some more text - there shouldn't be any padding on top of this one</section>
</div>
</div>
</div>
I am trying to determine if there is an easy way to adjust the CSS so that it can correctly identify a <section> in the next wrapper to set a value for top-padding
Also note, there is no way to remove the wrappers, and all the sections are already styled correctly, without them.

The sibling selector can not be used with elements that don't share the same hierarchy. See here for info:
The adjacent sibling combinator (+) separates two selectors and matches the second element only if it immediately follows the first element, and both are children of the same parent element.
Here are a few workarounds (assuming there are only 2 <section> per wrapper as your example depicts):
Give it another class that overrides the padding (by far the easiest)
Target only the nth element
Javascript
1 ) Just add a "no padding" class to any element you don't want padding added to:
section {
border: 1px solid black;
}
.wrapper1 > section {
padding-top: 2em;
padding-bottom: 2em;
}
.wrapper1 > section.pt-0 {
padding-top: 0;
}
<div id="layout1">
<div class="container1">
<div class="wrapper1">
<section class="option-b">This is some text</section>
</div>
<div class="wrapper1">
<section class="option-b pt-0">This is some more text - there shouldn't be any padding on top of this one</section>
</div>
<div class="wrapper1">
<section class="option-b pt-0">This is some more text - there shouldn't be any padding on top of this one</section>
</div>
<div class="wrapper1">
<section class="option-b">This is some text</section>
</div>
</div>
</div>
2 ) Target the nth element
section {
border: 1px solid black;
}
.wrapper1 > section {
padding-top: 2em;
padding-bottom: 2em;
}
.wrapper1:not(:first-child) > section {
padding-top: 0;
}
<div id="layout1">
<div class="container1">
<div class="wrapper1">
<section class="option-b">This is some text</section>
</div>
<div class="wrapper1">
<section class="option-b">This is some more text - there shouldn't be any padding on top of this one</section>
</div>
</div>
</div>
3) of course javascript:
const elems = document.querySelectorAll('#layout1 .wrapper1 > .option-b:not(.custom-bg-image)');
if (elems.length > 1) elems[1].style.paddingTop = 0;
section {
border: 1px solid black;
}
.wrapper1 > section {
padding-top: 2em;
padding-bottom: 2em;
}
<div id="layout1">
<div class="container1">
<div class="wrapper1">
<section class="option-b">This is some text</section>
</div>
<div class="wrapper1">
<section class="option-b">This is some more text - there shouldn't be any padding on top of this one</section>
</div>
</div>
</div>

Related

Remove redundant space at bottom when using Angular Flex with "row wrap" and grid-gap

I'm using Angular Flex to align cards in a row. The cards should wrap into a new line if there are several of them. The relevant settings of the block are
fxLayout="row wrap" fxLayoutGap="40px grid"
fxLayoutGap uses paddings on the inner elements and a negative margin on the container so that the gap is also applied when the inner elements wrap to a new row. So I do not want to remove the grid setting (or the paddings or negative margins in the
In addition, the cards are grouped into blocks with a header and a line on the left. I've created a sample that mirrors the settings that Angular Flex applies. The image is taken from this sample:
As you can see, there is redundant space at the bottom of each group. I want the block and the line on the left to end where the last row of cards (of the block) ends:
You can find the sample on jsfiddle.
How can I adjust the CSS and/or the Angular Flex settings to remove the redundant space and make the line end at the last row of cards while preserving the space between the blocks?
remove the padding-bottom from the last two elements:
#outer {
border-left: 2px solid red;
padding-left: 0px;
padding-bottom: 40px;
}
#outer:not(:first-child) {
margin-top: 40px;
}
#header {
padding: 10px;
margin: 0px 0px 40px 0px;
background-color: red;
}
#container {
margin: 40px -40px -40px 40px;
display: flex;
flex-flow: row wrap;
box-sizing: border-box;
}
#inner {
padding: 0px 40px 40px 0px;
flex: 0 0 50%;
box-sizing: border-box;
max-width: 50%;
min-width: 50%;
}
/* added */
#inner:last-child,
#inner:nth-last-child(2):nth-child(odd){
padding-bottom:0;
}
/**/
#card {
background-color: green;
}
<div id="outer">
<div id="header">
HEADER
</div>
<div id="container">
<div id="inner">
<div id="card">
CARD
</div>
</div>
<div id="inner">
<div id="card">
CARD
</div>
</div>
<div id="inner">
<div id="card">
CARD
</div>
</div>
<div id="inner">
<div id="card">
CARD
</div>
</div>
</div>
</div>
<div id="outer">
<div id="header">
HEADER
</div>
<div id="container">
<div id="inner">
<div id="card">
CARD
</div>
</div>
<div id="inner">
<div id="card">
CARD
</div>
</div>
</div>
</div>
<div id="outer">
<div id="header">
HEADER
</div>
<div id="container">
<div id="inner">
<div id="card">
CARD
</div>
</div>
</div>
</div>
<div id="outer">
<div id="header">
HEADER
</div>
<div id="container">
<div id="inner">
<div id="card">
CARD
</div>
</div>
<div id="inner">
<div id="card">
CARD
</div>
</div>
<div id="inner">
<div id="card">
CARD
</div>
</div>
</div>
</div>

prevent div from collapsing when hiding or removing all child elements

I created a Vuetify app managing some card items. Before adding the actions / buttons I check the User's permissions. If some permissions are missing these buttons will not be rendered. I created an example here
https://codepen.io/anon/pen/RmMRQb?editors=1010
As you can see the second div collapses because no children is rendered. This problem is not related to Vuetify, so I will reproduce it with default HTML / CSS example.
.container {
background: red;
}
.box {
display: inline-block;
height: 32px;
width: 32px;
margin: 5px;
background: blue;
}
.notRendered {
display: none;
}
<div id="app">
<h1>Div with visible elements</h1>
<div class="container">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
<h1>Div with hidden elements</h1>
<div class="container">
<div class="box notRendered">
</div>
<div class="box notRendered">
</div>
<div class="box notRendered">
</div>
</div>
</div>
I don't want the div to collapse. I already found a solution here
JQuery: Prevent div from collapsing when element hides()
but would like to ask if there is a way to achieve it without using some hardcoded heights or selecting the element's height. I don't want to modify Vuetify's native elements, so maybe there is a trick when the action bar is empty (no children got rendered) and the bar would not collapse.
I have added a secondary class for the default/native container. I think this is the best/easiest approach.
.improved-container {
background: red;
min-height: 40px;
}
.box {
display: inline-block;
height: 32px;
width: 32px;
margin: 5px;
background: blue;
}
.notRendered {
display: none;
}
<div id="app">
<h1>Div with visible elements</h1>
<div class="container improved-container">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
<h1>Div with hidden elements</h1>
<div class="container improved-container">
<div class="box notRendered">
</div>
<div class="box notRendered">
</div>
<div class="box notRendered">
</div>
</div>
</div>

How to stick bootstrap box together?

How to stick the columns together with bootstrap and css?
I would like to create something like this:
What I have created:
Here is my HTML & CSS markup:
<div class="container">
<div class="row">
<div class="col-md-4 ">
<div class="box1">
<h1>this is box 1 one</h1>
</div>
</div>
<div class="col-md-4 ">
<div class="box2">
<h1>this is box 1 one</h1>
</div>
</div>
<div class="col-md-4 ">
<div class="box3">
<h1>this is box 1 one</h1>
</div>
</div>
</div>
</div>
My css
.box1 {
background: red;
}
.box2{
background: green;
}
.box3 {
background: yellow;
}
Every single help would be appreciate!
There are many possibilities depending on what you are trying to achieve exactly.
If you want to remove the gap (called gutters) between ALL the columns of your design, you can customize your own bootstrap at http://getbootstrap.com/customize/#grid-system you'll see the variable "#grid-gutter-width" that needs to be set to 0.
If you want to have some contents that span outside the gutters, so they can touch adjascent elements, use a class to negate the gutter. Something like
.no-pad{
padding-left:0;
padding-right:0;
}
And add it to all columns you want without gutter.
If you want the background color to touch but still keep a nice sepperation of columns for your text, you can simply apply the background styles on the column itself.
The only way to achieve the result you are after is to remove the padding from Bootstraps column classes, like so:
.col-md-4 {
padding: 0;
}
However the above code will remove the padding from all col-md-4 column classes in your HTML. Best practise would be to add a unique class/ID and target the column that way, like so:
<div class="myClass">
<div class="container-fluid">
<div class="row">
<div class="col-md-4 ">
<div class="box1">
<h1>this is box 1 one</h1>
</div>
</div>
<div class="col-md-4 ">
<div class="box2">
<h1>this is box 1 one</h1>
</div>
</div>
<div class="col-md-4 ">
<div class="box3">
<h1>this is box 1 one</h1>
</div>
</div>
</div>
</div>
</div>
.myClass .row .col-md-4 {
padding: 0;
}
This way you are only targeting specific code and not ALL the columns.
Bootstraps grid system adds "gutters" or padding to each column. Is is this that you want to overwrite. however if you were to simply apply padding:0px; to .col-md-4 you would remove padding from all instances of .col-md-4 which is unlikely.
The way around this would be to give a class to the "row" container which you can then target only instances of .col-md-4 within that class. In this example I have added the class boxes to the row. then in the css I use:
.boxes .col-md-4 {
padding-right: 0;
padding-left: 0;
}
this way, my padding changes are restricted to col-md-4 classes that are children of a boxes class.
I hope that helps.
Working example but using col-xs-4 as much smaller viewport:
.row {
background: #ccc;
}
.box {
height: 100px;
margin-bottom: 20px;
overflow: hidden;
}
.boxes .col-xs-4 {
padding-right: 0;
padding-left: 0;
}
.box1 {
background: red;
}
.box2 {
background: green;
}
.box3 {
background: yellow;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="container">
<div class="row boxes">
<div class="col-xs-4">
<div class="box box1">
<h1>this is box 1</h1>
</div>
</div>
<div class="col-xs-4 ">
<div class="box box2">
<h1>this is box 2</h1>
</div>
</div>
<div class="col-xs-4 ">
<div class="box box3">
<h1>this is box 3</h1>
</div>
</div>

Bootstrap full width sections with graphical backgrounds

I am trying to implement a design from my graphic designer, which whilst looks cool is giving me some headaches as i don't know how to implement in bootstrap.
We have a call to action section, which aligns with the 12 column grid system on its left and right extremes.
It also stretches to the view-port edges:
On the left we have red background stretching all the way to the view-port edge.
On the right we have a grey background image stretching all the way to the view-port edge.
I haven't been able to find a search term for what I am looking to achieve let alone where to start (other than have the cta use the background for the entire width, then overlay a left element over the top).
Any idea on how to code the below graphical layout in bootstrap please?
<section class="cta" style="background: grey; position: relative">
<div class="red" style="position: absolute; left: 0; width: 10%; background: red"></div>
<div class="text-outer">
<div class="container">
<div class="row">
<div class="col-xs-6">left</div>
<div class="col-xs-6">right</div>
</div>
</div>
</div>
</section>
Using <div class="container-fluid"> as a starting point; I am guessing at your page's layout. Let's try this:
See below:
.cntn {
border: 1px red solid; /* you can remove this (not needed) */
}
.red {
background-color: red;
text-align: right;
margin: 0; /* optional */
width: 100px; /* adjust to suit your needs */
float: left;
}
.cta {
margin: 0; /* optional */
float: right;
border: 1px solid green; /* you can remove this (not needed) */
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- make container fluid -->
<div class="container-fluid">
<div class="row">
<!-- heading area: hexagon -->
<div class="red">
<img src="http://placehold.it/100/100" />
</div>
<!-- heading area: call-to-action -->
<section class="cta">
Action
</section>
</div>
<div class="row cntn">
<div class="col-xs-6">left</div>
<div class="col-xs-6">right</div>
</div>
</div>
Simply change 'div class="container"' to 'div class="container-fluid"'
Something like this? Where black should be the grey gradient and max-width:400px could be anything.
.cta {
overflow-x: hidden;
position: relative
}
.text-outer .container {
width: 100%;
max-width: 400px;
background: grey;
z-index: 2;
position: relative;
}
.text-outer:before,
.text-outer:after {
content: "";
position: absolute;
width: 50%;
height: 100%;
top: 0;
}
.text-outer:before {
background-color: red;
left: 0;
}
.text-outer:after {
background-color: black;
right: 0;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<section class="cta">
<div class="text-outer">
<div class="container">
<div class="row">
<div class="col-xs-6">left</div>
<div class="col-xs-6">right</div>
</div>
</div>
</div>
</section>
jsFiddleLink
I created with 3 divs as Left Center and Right but if you want to use Left and center then create your own class. Probably following will work
.custom {
width:calc(100% - (50% - 768px/2));
}
.custom {
width:calc(100% - leftCellWidth);
}
You can set height of left as per height of hex image.
Use jumbotron class outside the class container for full-width, as explained here.
HTML:
<div class="jumbotron">
<div class="container">
<div class="row">
<div class="red col-xs-4">
</div>
<div class="grey col-xs-8">
</div>
</div
</div>
</div>
CSS:
.red {
background: url('awesomeredimage.png');
background-size: cover;
}
.grey {
background: url('awesomegreyimage.png');
background-size: cover;
}
All your divs should be wrapped in the container div. And as some others have also suggested: container-fluid helps.
Within container fluid you can add a regular container for the rest of your content. My code below explains this.
You could take the easy route and just use the entire cta image you've posted as a clickable image with .img-responsive in a col-xs-12. In that case my fix takes you about 2 minutes:
<section style="background: grey; position: relative">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
<img src="/img/cta.jpg" class="img-responsive">
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="container">
<!-- All you other content here-->
</div>
</div>
</div>
</div>
</section>
But you could also hack the design into cols, as I try to show in the code snippet below. Of course you need to tweak and decide on the exact sizes yourself.
<section style="background: grey; position: relative">
<div class="container-fluid">
<div class="row">
<div class="col-xs-3 red">
<img src="/img/hexagon.png" class="img-responsive pull-right">
<!--and give this img a negative margin to flow over to the grey area-->
</div>
<div class="col-xs-1 grey-image"></div>
<div class="col-xs-3 grey-image">
<h3 class="text-center">Call to action</h3>
<p class="text-center">Discount etcetera</p>
</div>
<div class="col-xs-5 grey-image">
<button class="btn center-block">Request quote</button>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="container">
<!-- All you other content here-->
</div>
</div>
</div>
</div>
</section>
Use class="container-fluid" instead of class="container" and than do this style:
.container-fluid {
margin-right: auto;
margin-left: auto;
padding-left: 0px;
padding-right: 0px;
}

:hover command won't work with a general sibling selector

I am trying to have a display that changes when hovering a div class. The idea is to have one div disappear when hovering another. I have tried using general sibling selectors to make the display change from inline to none. The CSS is as follows:
#Inicio {width: 100%;
height: 100%;
background-color: yellow;
position: absolute;
display: inline;
}
.buttons:hover ~ #Inicio {display: none;}
.buttons {width: 80%;
margin-left: auto;
margin-right: auto;
position: static;
margin-left: 10%;
font-size: 22px;
border-top: 1px solid white;
padding-top: 20px;
padding-bottom: 20px; }
.buttons:hover {font-size: 24px;
transition: all .5s ;}
And the HTML:
<div id="wrapper">
<div id="menubar">
<div id="menu">
<h1>Menu</h1>
</div>
<div class="buttons">
Inicio
</div>
<div class="buttons">
Productos
</div>
<div class="buttons">
Localizacion
</div>
<div class="buttons">
El equipo
</div>
<div class="buttons">
Ideas
</div>
<div class="buttons">
La pagina
</div>
</div>
<div id="content">
<div id="inicio"></div>
</div>
</div>
First of all, your id names doesn't match, its case sensitive, you #inicio and #Inicio are completely two different things..
And as I commented, the issue is that you cannot pop out of the element using CSS means you cannot select the parent element and than go ahead and select the parents sibling element, so you need to change your DOM, you are trying to select an element which is adjacent to the buttons parent element and not the button itself, so the best you can do is this
.buttons:hover ~ #content > #inicio {
display: none;
}
Demo
Altered DOM, you need to bring the elements on the same level, if #inicio is nested, it's fine, but to select it's parent, bring the elements adjacent to each other on the same level so that all are direct child to an element having an id of #wrapper
<div id="wrapper">
<div id="menu">
<h1>Menu</h1>
</div>
<div class="buttons">
Inicio
</div>
<div class="buttons">
Productos
</div>
<div id="content">
<div id="inicio">Disappear this</div>
</div>
</div>
As #enguerranws commented, I thought to put a compatibility table as well,
Credits - Support Table
Maybe because it's #inicio, not #Inicio ?
Then you need to change your DOM. You have to put #inicio in .buttons div. Or :
.buttons:hover ~ #Inicio
Won't work.
<div id="wrapper">
<div id="menubar">
<div id="menu">
<h1>Menu</h1>
</div>
<div class="buttons">
<span>Inicio</span>
<div id="inicio"></div>
</div>
</div>
<div id="content">
</div>
</div>
You should use that structure. Btw, I added a span to wrap your text, as it's not valid to put text directly in block element (here: div).