CSS: Aligning divs 2 on a line without using float [duplicate] - css

This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 4 years ago.
I am trying to avoid using float. When I lower the width to 49%, they sit side by side but unevenly. When I raise the width to 50%, each div sits on it's own line so I'm not sure why.
body {
margin: 0px;
padding: 0px;
}
div {
min-height: 50vh;
width: 50%;
display: inline-block;
}
div:nth-child(1) {
background-color: red;
}
div:nth-child(2) {
background-color: green;
}
div:nth-child(3) {
background-color: blue;
}
div:nth-child(4) {
background-color: yellow;
}
<div>Red</div>
<div>Green</div>
<div>Blue</div>
<div>Yellow</div>

Because inline-block respect space character, in this case, each element puts a "character" space between the divs. Do avoid this there are some tricks but I suggest you to use css grid:
body {
display: grid;
grid-template-columns: 1fr 1fr;
}

display: inline; and display: inline-block uses text spacing as opposed to display: block which will position items more precisely.
By moving the divs to a single line, this forces the divs to have zero space in between them.
See this article for more information.
body {
margin: 0px;
padding: 0px;
}
div {
min-height: 50vh;
width: 50%;
display: inline-block;
}
div:nth-child(1) {
background-color: red;
}
div:nth-child(2) {
background-color: green;
}
div:nth-child(3) {
background-color: blue;
}
div:nth-child(4) {
background-color: yellow;
}
<div>Red</div><div>Green</div><div>Blue</div><div>Yellow</div>

You should use flexbox.
you would need to wrap your divs in another div width the class="container"
then you could do this
.container {
display: flex; /* display side by side */
align-items: center; /* align vertically */
}
.container > * {
flex: 1;
}

If you need to use inline-block make sure you write your html without any spaces.
this does not work:
<div>Red</div>
<div>Green</div>
<div>Blue</div>
<div>Yellow</div>
this does work:
<div>Red</div><div>Green</div><div>Blue</div><div>Yellow</div>

Related

is there a way to make this less text and less complicated?

started to learn HTML and CSS, I want 4 blocks, 2 centred and 1 on each side, left and right. And if resize the window the block distance between the outer and inner blocks varies and the borders never cut each other
this is the full css code, I have the feeling I did this way too complicated.. I mean it works but yeah..
section {
display: inline-block;
position: relative;
width: 100vw;
height: 100vw;
background-color: blue;
}
.hm {
display: inline-block;
position: fixed;
top: 50%;
padding: 20px;
margin: 20px;
border: 10px solid yellow;
width: 60px;
height: 60px;
transform: translateX(-25%); translate: 10px;
}
.hm0 {
display: inline-block;
position: fixed;
top: 50%;
left: 50%;
padding: 20px;
margin: 20px;
border: 10px solid red;
width: 60px;
height: 60px;
transform: translate(-20px);
}
.hm1 {
display: inline-block;
position: fixed;
top: 50%;
left: 50%;
padding: 20px;
margin: 20px;
border: 10px solid rgb(211, 208, 208);
width: 60px;
height: 60px;
transform: translate(-100%); translate: -20px;
}
.hm2 {
display: inline-block;
position: fixed;
top: 50%;
right: 0;
padding: 20px;
margin: 20px;
margin-left: auto;
margin-right: 0;
border: 10px solid rgb(255, 0, 225);
width: 60px;
height: 60px;
}
<body>
<section>
<div class="hm"></div>
<div class="hm0"></div>
<div class="hm1"></div>
<div class="hm2"></div>
</section>
</body>
I am not sure if this is what you are going for, but I have attempted to recreate it with Flexbox.
First, I wrapped the blocks that should be in the center in another div as follows:
<section>
<div class="hm box"> </div>
<div class="center">
<div class="hm0 box"> </div>
<div class="hm1 box"> </div>
</div>
<div class="hm2 box"></div>
</section>
I also added a class box that will contain the height and width of each box.
With that, I styled them like so:
section {
display: flex;
justify-content: space-between;
align-items: center;
width: 100vw;
height: 100vw;
background-color: blue;
}
.center {
display: flex;
}
.hm {
border: 10px solid yellow;
}
.hm0 {
border: 10px solid red;
}
.hm1 {
border: 10px solid rgb(211, 208, 208);
}
.hm2 {
border: 10px solid rgb(255, 0, 225);
}
.box {
width: 60px;
height: 60px
}
The most important styles concerning the layout are here:
section {
display: flex;
justify-content: space-between;
align-items: center;
width: 100vw;
height: 100vw;
background-color: blue;
}
display: flex;: aligns all blocks horizontally(except the blocks in the .center div, because they are not the section element direct children)
justify-content: space-between;: this pushes the first and last blocks to the edges of the section element, leaving the center div elements in the center.
align-items: center;: aligns all the horizontal blocks in the center of the section element.
Now since the blocks in the center div are not direct descendants of section element, I also used display:flex to align them horizontally:
.center {
display: flex;
}
To learn more about flexbox and its properties, check out flexboxfroggy
You can checkout the demo of the code here:
https://jsfiddle.net/stanulilic/s7oh4nv9/
To re-write your posted CSS in a more concise form leads us to the following, explanatory comments are in the CSS:
/* this is a personal style or affectation that I tend to list
CSS properties alphabetically, that way if you're looking to
see if a property is set I know where to find it, and if it's
not where I expect it to be I know it hasn't been set on that
element/selector. This is a personal style, it's not mandatory
it's probably not even 'best-practice,' but you'll help yourself
if you pick a particular approach and then stick with it: */
section {
background-color: blue;
display: inline-block;
height: 100vw;
position: relative;
width: 100vw;
}
/* the following selector matches the four <div> elements within the
<section> element, and the child combinator (the '>') prevents the
selector matching any <div> elements nested within those child
elements. This selector then applies all common CSS styles for all
the child elements, to avoid redeclarations: */
section > div {
/* all <div> elements have a 10px solid border, so here we apply
that border with the color set to 'transparent,' allowing us to
set the 'border-color' in the individual elements: */
border: 10px solid transparent;
display: inline-block;
height: 60px;
padding: 20px;
margin: 20px;
position: fixed;
top: 50%;
width: 60px;
}
.hm {
/* setting the border-color for this specific element: */
border-color: yellow;
/* the following translations were combined into one
'translate' declaration, using the calc() method:
transform: translateX(-25%);
translate: 10px;
*/
translate: calc(-25% + 10px);
}
.hm0 {
/* again, setting properties specific to the individual elements: */
border-color: red;
left: 50%;
translate: -20px;
}
.hm1 {
border-color: rgb(211, 208, 208);
left: 50%;
/* combining the two different translations into one single declaration
via translate: calc(...):
transform: translate(-100%);
translate: -20px;
*/
translate: calc(100% - 20px);
}
.hm2 {
border-color: rgb(255, 0, 225);
margin-left: auto;
margin-right: 0;
right: 0;
}
<section>
<div class="hm"></div>
<div class="hm0"></div>
<div class="hm1"></div>
<div class="hm2"></div>
</section>
JS Fiddle demo.
Things to learn from the above snippet/approach:
try to group all common styling together under one selector that can apply to the each element of a group as a whole, two
use the same properties to do the same thing; don't combine functions and properties such as – for example – transform: translate() (or translateX()) with translate,
if you find you're having to use a property/function and then use a different property/function to further adjust, consider looking for a way to combine the two adjustments into one (the calc() function being a much-used, and versatile, way of doing so),
try and adopt an approach of organising your code in such a way that it becomes easy and predictable to find a property-value pair in your code, particularly CSS, where it's incredibly easy to just add amendments or additions to the end of a rule-set.
Now, the above layout can be achieved more easily using either CSS flex layout, or CSS Grid.
First, flex-box:
/* a simple CSS reset, to ensure all browsers size elements the same way,
using the border-box algorithm, to include borders and padding in the
declared sizing: */
*,
::before,
::after {
box-sizing: border-box;
/* removing browser-default margins and padding: */
margin: 0;
padding: 0;
}
section {
/* here we align the items within the <section> to the
vertical center; align-items works on the cross-axis
which is perpendicular to the main-axis; the main-
axis default is 'row' (so horizontal), therefore by
default 'align-items' positions the flex-items (the
elements within the flex-box) on the vertical axis:*/
align-items: center;
background-color: blue;
block-size: 100vh;
/* specifying the flex-layout: */
display: flex;
/* positioning elements to the center on the main-axis,
horizontal by default: */
justify-content: center;
}
section > div {
/* ensures that the element's width and height are equal: */
aspect-ratio: 1;
/* defining the borders of all elements matched by the
selector: */
border: 10px solid transparent;
/* defining the block-size of the matched elements; this is
a CSS logical property, and in European languages - and
others descended from those languages - is equivalent to
'height'; and the previous use of 'aspect-ratio'
automatically sets the 'inline-size' (equivalent to 'width'
in European languages and their descendants): */
block-size: 60px;
padding: 20px;
}
.hm {
border-color: yellow;
/* to move this element as far as possible to the inline-start
(the left, for European languages) we use the following to
add an auto-sized margin to the inline-end (in European
languages that's the 'right') side: */
margin-inline-end: auto;
}
.hm0 {
border-color: red;
}
.hm1 {
border-color: rgb(211, 208, 208);
}
.hm2 {
border-color: rgb(255, 0, 225);
/* as above - for .hm - we want to move this element to the
inline-end (the 'right,' in European languages...) side,
so we again set an auto margin on the opposing side, the
'inline-start' ('left,' in European languages): */
margin-inline-start: auto;
}
<section>
<div class="hm"></div>
<div class="hm0"></div>
<div class="hm1"></div>
<div class="hm2"></div>
</section>
JS Fiddle demo.
And, finally, CSS Grid layout:
/* a simple CSS reset, to ensure all browsers size elements the same way,
using the border-box algorithm, to include borders and padding in the
declared sizing: */
*,
::before,
::after {
box-sizing: border-box;
/* removing browser-default margins and padding: */
margin: 0;
padding: 0;
}
section {
align-items: center;
background-color: blue;
block-size: 100vh;
/* specifying the flex-layout: */
display: grid;
grid-template-columns: repeat(4, 1fr);
}
section > div {
/* ensures that the element's width and height are equal: */
aspect-ratio: 1;
/* defining the borders of all elements matched by the
selector: */
border: 10px solid transparent;
/* defining the block-size of the matched elements; this is
a CSS logical property, and in European languages - and
others descended from those languages - is equivalent to
'height'; and the previous use of 'aspect-ratio'
automatically sets the 'inline-size' (equivalent to 'width'
in European languages and their descendants): */
block-size: 60px;
padding: 20px;
}
/* selecting the odd-numbered <div> elements within the <section>,
the first and third: */
section > div:nth-child(odd) {
/* positioning them to the inline-start by setting their
margin-inline-end (right, in European languages...) to
'auto': */
margin-inline-end: auto;
}
/* selecting the even-numbered <div> elements within the <section>,
the second and fourth: */
section > div:nth-child(even) {
/* positioning them to the inline-end, by setting the opposing
margin - margin-inline-start - to auto: */
margin-inline-start: auto;
}
.hm {
border-color: yellow;
}
.hm0 {
border-color: red;
}
.hm1 {
border-color: rgb(211, 208, 208);
}
.hm2 {
border-color: rgb(255, 0, 225);
}
<section>
<div class="hm"></div>
<div class="hm0"></div>
<div class="hm1"></div>
<div class="hm2"></div>
</section>
JS Fiddle demo.
References:
align-content.
align-items.
aspect-ratio.
background-color.
block-size.
border.
border-color.
box-sizing.
calc().
CSS Logical Properties.
display.
grid-template-columns.
height.
inline-size.
justify-content.
justify-items.
margin.
margin-block.
margin-block-end.
margin-block-start.
margin-inline.
margin-inline-end.
margin-inline-start.
padding.
padding-block.
padding-block-end.
padding-block-start`.
padding-inline-end.
padding-inline-start.
place-items.
repeat().
transform.
translate (CSS property).
translate() (CSS function).
width.

CSS: Background color on text doesn't work when the line breaks in responsive mode [duplicate]

This question already has answers here:
Thick underline behind text
(7 answers)
Closed 8 months ago.
I am trying to use a background color on text only, which works fine on single lines, but when the line breaks in responsive mode it ends up looking like this:
Does anyone know what to add to make the yellow background line follow the text on mulitple lines?
This is my code:
.background-highlight {
position: relative;
display: inline-block;
color: #faf9f4;
}
.background-highlight:after {
content: '';
position: absolute;
width: 100%;
height: 10px;
left: 0;
top: 50%;
background-color: #cef230;
z-index: -1;
}
Thanks a lot in advance,
I have used box-decoration-break: clone; property for mainting the same design for multiple lines don't forget to add display: inline; to its child where background is added. in child I have used linear gradient you can generate according to you from here. you can chenge the position of green strip by adjusting gradient values from the site.
.background-highlight {
position: relative;
display: inline-block;
color: #000;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
font-size: 120px;
}
.background-highlight span {
display: inline;
background: rgb(206,242,48);
background: -webkit-gradient(linear, left bottom, left top, color-stop(11%, rgba(206,242,48,1)), color-stop(12%, rgba(255,255,255,0)));
background: -o-linear-gradient(bottom, rgba(206,242,48,1) 11%, rgba(255,255,255,0) 12%);
background: linear-gradient(0deg, rgba(206,242,48,1) 11%, rgba(255,255,255,0) 12%);
}
<h1 class="background-highlight"><span>The skippers escape</span></h1>
It is fault of pseudo element that is forced to break between two lines.
The cause is the way the effect is carried out, pseudo element ::before creates a single rectangle that has no way of splitting up to follow words flow. Posible solutions:
Make sure links never occupy more than 1 line. You can use
white-space: nowrap;
Redesign the effect applying box border to main element. For example:
.background-highlight {
width: max-content;
border-bottom:5px solid rgb(217, 255, 0);
}
<div class="background-highlight">THE SKIPPER´S ESCAPE</div>
Pseudo-element solution
Use the bottom-positioning value on the pseudo-element instead of top. This forces the pseudo-element to be positioned at the bottom, instead of 50%from the top. I used bottom: -10px as that is the height of the pseudo-element, so it aligns perfectly.
Read more on position values: https://developer.mozilla.org/en-US/docs/Web/CSS/position
HTML-element solution
Instead of creating a pseudo-element, you could opt to make an HTML element instead.
Make a parent container, apply flex to it so the text and the line will align.
Make the .line-element a block element, so it will break into a new line.
You can still apply position: absolute and position: relative on the .line and the h2 if you want to position it in another way. Or you could simply use e.g. transform: translateY(5px) to move the line up a bit.
.background-highlight {
position: relative;
display: inline-block;
color: black;
text-align: right;
}
.background-highlight:after {
content: '';
position: absolute;
width: 100%;
height: 10px;
left: 0;
bottom: -10px;
background-color: #cef230;
z-index: -1;
}
/* Without pseudo */
.nopseudo {
display: flex;
}
.nopseudo h2 {
text-align: right;
}
.nopseudo .line {
height: 10px;
width: 100%;
background-color: #cef230;
display: block;
}
<h2 class="background-highlight">The Skippers <br>Escape</h2>
<div class="nopseudo">
<h2>The Skippers <br>Escape<span class="line"></span></h2>
</div>
I don't know how is your structure but this might help.
We just need two div elements, one as a container to setup the width property and the text holder in this case I will use a h2 tag.
Just mkae the ::after pseudo element as display and the .background-highlight's width can be width: match-content or 100% in this case if you just want to cover the text use match-content if you want to cover the width of the .title element use 100%
.title {
width: 90vw;
text-align: end;
}
h2 {
text-transform: uppercase;
color: #374650;
}
.fullwidth {
width: 100%;
}
.match {
width: match-content;
}
.background-highlight {
position: relative;
display: inline-block;
}
.background-highlight:after {
content: '';
display: block;
width: 100%;
height: 10px;
background-color: #cef230;
z-index: -1;
}
<div class="title">
<h2 class="match background-highlight">
The Skipper's <br>Escape</h2>
</div>
<div class="title">
<h2 class="fullwidth background-highlight">
The Skipper's <br>Escape</h2>
</div>

Layer div with css shape cut-out over a div with bg color

I'm trying to indicate the active link, using a triangle-shaped CSS "cut-out" (the triangle is cut out of the white header.
http://codepen.io/Goatsy/pen/xVvRmZ
/*
.container {
width: 1200px;
}
*/
How do I "cut out" the red triangle from both the contained header and full-width background (red) block? I need to cut out the triangle to expose underlying photo.
The header works great, but as soon as the full-width red block is applied to the background layer of contained header, it "fills in" the triangle cut-out.
UPDATE:
I created a flexbox within a flexbox. Unfortunately, the contained header is not exactly 1200px, and this will be difficult to apply to the overall layout.
http://codepen.io/Goatsy/pen/xVvRmZ
.wrapper-whole {
display: flex;
flex-direction: row;
height: 134px;
margin: auto;
}
.flexy {
background: #f00;
flex: 2;
height: 134px;
}
.wrapper { /* wraps contained header navbar */
display: flex;
flex-direction: row;
height: 134px;
border-left: 15px solid #fff;
border-right: 15px solid #fff;
max-width: 1200px;
margin: auto;
flex: 6;
}
Instead of cutting it out from a background, you could create the illusion of a background by making red elements on each side of the white header using :before and :after pseudo-elements.
In http://codepen.io/anon/pen/MyNpdX, I added the following CSS:
.wrapper {
/* the stuff that was already here */
position: relative;
}
.wrapper:after, .wrapper:before{
content: "";
background-color: #f00;
width: 4000px;
position: absolute;
height: 134px;
top: 0;
}
.wrapper:before{
margin-right: 15px;
right: 100%;
}
.wrapper:after{
left: 100%;
margin-left: 15px;
}
Too many questions:
let me try to answer the ones I've understood.
I'll keep editing this answer as I go:
to contain something: you can have the following parent div
.parent {
max-width: 1200px;
overflow: hidden;
}
this way a child red div, would not appear outside parents constraint.
you can achieve css-triangles as:
.arrow-up {
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 15px solid black;
}
<div class="arrow-up"></div>
p.s.: you're codepen is so far behind the layout in question, that it's hard to hands-on fix the problem
Place the contained flexbox header, inside of another flexbox.
Place one (red) block on left of header and one (red) block on right.
Create max-width for white header:
#media screen and (min-width: 480px) {
.wrapper { /* wraps contained header navbar */
min-width: 1200px;
}
}
http://codepen.io/Goatsy/pen/xVvdKN

Flexbox: Single Column to Stacked Multi-Column

I encounter this layout issue a lot:
Small screens - items are stacked in a single row, usually an image followed by some text, then a smaller sub-area for extra miscellaneous:
Medium screens and up - items are reshuffled to 2 columns, image and misc stuff on the left, text on the right:
I feel like I should be able to do this with flexbox, but I can't figure out how. I get that I can arrange the items in columns using:
.container {
display: flex;
flex-flow: column wrap;
}
.one,
.two,
.three {
width: 50%;
}
.one {
order: 1;
}
.two {
order: 3;
}
.three {
order: 2;
}
But the problem is there doesn't seem to be a way to break the items into 2 columns without setting a fixed height, which obviously doesn't work too well for responsive.
Is there a way to force the columns to break at certain points?
You can do it like this. By making width 100% at mobile size. they take up their own line.
.container {
width: 75%;
margin: 0 auto;
}
.box1, .box2, .box3 {
width: 50%;
}
.box1 {
background-color: blue;
float:left;
}
.box2 {
background-color: green;
float: right;
}
.box3 {
background-color: purple;
float: left;
}
#media screen and (max-width: 800px) {
.box2 {
float: left;
}
.box1,.box2,.box3 {
width: 100%;
}
}
JSFIDDLE

Arrange inline-block divs nicely

I have a set of divs with this layout:
div.post_summary {
clear: none;
width: 170px;
display: inline-block;
float: left;
margin: 5px;
background-color: #FF5900;
}
It now looks like:
But I want it to look like:
The order of the divs in no way matters. How can I do this?
Since order doesn't matter, you can do this with CSS columns:
http://codepen.io/cimmanon/pen/CcGlE
div.container { /* container holding all of your `div.post_summary` elements */
columns: 20em; /* desired width of the columns */
}
div.post_summary {
margin: .5em;
background-color: #CCC;
}
div.post_summary:first-child {
margin-top: 0;
}
Make sure you check http://caniuse.com/#feat=multicolumn to see which prefixes you need.

Resources