display property of a CSS element is foundational to understanding CSS. In this post, we will continue building up our foundations from the previous post by examining the
display property and understanding a bit more on how to properly style buttons and links.
By default, block level elements create a new line of content in the HTML document. Moreover, they stack on top of each other creating a series of rows. These elements are block elements by default: Paragraphs, Headings, Lists, list items, divs, header, footer, main and section. Block level elements have a default width of 100% and a default height of 0, but they will grow in height according to the content that is inside of them. The block level element’s width of 100% will take up the full width of its parent element. If the block level element’s parent is the
body then the block level element will take the full width of the page, in proportion to the size of the browser.
Sure, there are aspects of HTML and CSS that can be relatively easy to learn at first with a “monkey see; monkey do” approach. The feedback one receives in writing HTML / CSS is instant. Just reload the browser and gaze at your yellow square on the page. Now let’s center the yellow square. See! Easy.
Margin is empty space. Margin pushes elements away. However, margins on adjacent elements can merge. If for instance there’s two elements stacked on top of each other — display block. Let’s say the top element adds 50 pixels of padding on it’s bottom perimeter and the bottom element adds 50 pixels of padding on the top perimeter. One may be tempted to think that these two elements have created 100 pixels of empty space between themselves. This assumption is incorrect, however. In fact there would be only 50 pixels of distance between these two elements because margins collapse onto of each other. Other margins from other elements, when they meet, their margins do not push each other away. Their margins collapse on top of each other.
Here’s a code pen for demonstration.
For this site, I have a local set up which allows me to add new features as well as publish content like this very blog post you are reading. In part 1 I showed you how the site is set up in the cloud with AWS services like S3, ACM, Cloudfront and Route53 . In this post I will show you how I add new features to my site, deploy changes and add content like this very blog post.
At a high level my local set up includes:
- a deploy script leveraging AWS’s awscli to upload html, CSS and JS files to an s3 bucket
- Rails which powers the app process running my site locally
- Wordpress, serving as the CMS that I write my blog posts into
- MySQL, which stores the posts saved from Wordpress
- Redis which contains my cached blog posts
- three dot files that allows me to leverage environment variable data per QA, Production and local environment
- redcarpet for markdown parsing and rouge for code syntax highlighting
Intro: Watch out! This is a long post and most likely will be updated over time as I go through the motions of setting up a site as I describe below with a friend. If any of the below information is inaccurate or unclear please email me at the information provided under about / contact.
As an application developer, I am very comfortable with local development. Once I have an app or a technology installed and set up -- the set up on my computer or the configuration harness for the technology is usually the hardest part for me -- I am good to go. Once I have what I need running on my machine, I am ready and excited to start developing. However, when it comes to managing software in “the cloud”, I can get a little nervous because managing infrastructure is not my strongest suit.
The fact is sad but true -- unlike applications, their processes, libraries, design patterns and language specifications, I do not understand sufficiently enough in my opinion the systems and infrastructure upon which these applications rely. These systems -- such as, IP/TCP, firewalls, security groups, servers, DNS, TLS, Operating Systems, Virtual Machines and Containerized Environments, just to name a short list of very important systems that many applications rely upon -- make applications available to users for consumption. Without these systems, the applications that we developers create will just stay on our machines, and there will be neither users nor customers to enjoy our creations.
This great article discusses how either avoiding conditionals entirely or refactoring them out of an application can make a codebase easier for developers to understand and change. To expand on how
culling conditionals with abstractions not only works in terms of implementation but also improves the cleanliness of a codebase, we will take the same examples from the above article, modify them slightly and provide a detailed implementation of the abstractions working together.
Hopefully, this demonstration will make the message more clear on why conditionals can add unnecessary complexity and confusion and how removing them with abstractions will create a simpler and more flexible solution. Moreover, further detailed examples will bring into the discussion the tradeoffs a developer must consider when
culling conditionals with abstractions.
According to the author, conditionals are confusing and on top of being confusing they tend to spread and multiply throughout a codebase. To better understand how conditionals are confusing and spread throughout a code base, read the sections of the post, Conditionals Spread, and, Conditionals are Confusing. In short, developers tend to make the most obvious change so that development can be deployed to production
safely. The convenience of conditionals means they tend to spread. Furthermore, conditionals are confusing because while looking at a conditional a developer must keep a lot in his head at once: the implementation of all of the branches of the conditional tree.